Recherche de site Web

Les réseaux de neurones sont des algorithmes d'approximation de fonctions


L'apprentissage supervisé dans l'apprentissage automatique peut être décrit en termes d'approximation de fonctions.

Étant donné un ensemble de données composé d'entrées et de sorties, nous supposons qu'il existe une fonction sous-jacente inconnue qui est cohérente dans le mappage des entrées aux sorties dans le domaine cible et qui a abouti à l'ensemble de données. Nous utilisons ensuite des algorithmes d’apprentissage supervisé pour approximer cette fonction.

Les réseaux de neurones sont un exemple d’algorithme d’apprentissage automatique supervisé qui est peut-être mieux compris dans le contexte de l’approximation des fonctions. Cela peut être démontré avec des exemples de réseaux de neurones se rapprochant de fonctions unidimensionnelles simples qui aident à développer l'intuition de ce qui est appris par le modèle.

Dans ce tutoriel, vous découvrirez l'intuition derrière les réseaux de neurones en tant qu'algorithmes d'approximation de fonctions.

Après avoir terminé ce tutoriel, vous saurez :

  • La formation d'un réseau neuronal sur des données se rapproche de la fonction de cartographie sous-jacente inconnue des entrées aux sorties.
  • Les ensembles de données d'entrée et de sortie unidimensionnelles fournissent une base utile pour développer les intuitions de l'approximation des fonctions.
  • Comment développer et évaluer un petit réseau neuronal pour l'approximation des fonctions.

Démarrez votre projet avec mon nouveau livre Deep Learning With Python, comprenant des tutoriels pas à pas et les fichiers code source Python pour tous exemples.

Commençons.

Présentation du didacticiel

Ce didacticiel est divisé en trois parties : ils sont:

  1. Qu'est-ce que l'approximation de fonction
  2. Définition d'une fonction simple
  3. Approximation d'une fonction simple

Qu'est-ce que l'approximation de fonction

L'approximation de fonction est une technique permettant d'estimer une fonction sous-jacente inconnue à l'aide d'observations historiques ou disponibles dans le domaine.

Les réseaux de neurones artificiels apprennent à se rapprocher d'une fonction.

Dans l'apprentissage supervisé, un ensemble de données est composé d'entrées et de sorties, et l'algorithme d'apprentissage supervisé apprend à mapper au mieux des exemples d'entrées à des exemples de sorties.

On peut penser que cette cartographie est gouvernée par une fonction mathématique, appelée fonction de cartographie, et c'est cette fonction qu'un algorithme d'apprentissage supervisé cherche à mieux approximer.

Les réseaux de neurones sont un exemple d'algorithme d'apprentissage supervisé et cherchent à se rapprocher de la fonction représentée par vos données. Ceci est réalisé en calculant l'erreur entre les résultats prédits et les résultats attendus et en minimisant cette erreur pendant le processus de formation.

Il est préférable de considérer les réseaux de rétroaction comme des machines d’approximation de fonctions conçues pour réaliser une généralisation statistique, tirant parfois quelques enseignements de ce que nous savons sur le cerveau, plutôt que comme des modèles de fonctions cérébrales.

— Page 169, Apprentissage profond, 2016.

Nous disons « approximatif » car même si nous soupçonnons qu'une telle fonction de cartographie existe, nous n'en savons rien.

La véritable fonction qui mappe les entrées aux sorties est inconnue et est souvent appelée la fonction cible. C'est la cible du processus d'apprentissage, la fonction que nous essayons d'approcher en utilisant uniquement les données disponibles. Si nous connaissions la fonction cible, nous n’aurions pas besoin de l’approcher, c’est-à-dire que nous n’aurions pas besoin d’un algorithme d’apprentissage automatique supervisé. Par conséquent, l’approximation de fonction n’est un outil utile que lorsque la fonction de mappage cible sous-jacente est inconnue.

Tout ce dont nous disposons, ce sont des observations du domaine qui contiennent des exemples d’entrées et de sorties. Cela implique des éléments concernant la taille et la qualité des données ; Par exemple:

  • Plus nous avons d’exemples, plus nous pourrons peut-être comprendre la fonction de cartographie.
  • Moins nous avons de bruit dans les observations, plus nous pouvons faire une approximation précise de la fonction de cartographie.

Alors pourquoi aimons-nous utiliser les réseaux de neurones pour l’approximation des fonctions ?

La raison en est qu'ils constituent un approximation universelle. En théorie, ils peuvent être utilisés pour approximer n’importe quelle fonction.

… le théorème d'approximation universelle déclare qu'un réseau à action directe avec une couche de sortie linéaire et au moins une couche cachée avec n'importe quelle fonction d'activation « d'écrasement » (telle que la fonction d'activation sigmoïde logistique) peut approximer n'importe quelle fonction […] à partir d'un espace de dimension finie à un autre avec n'importe quelle quantité d'erreur non nulle souhaitée, à condition que le réseau reçoive suffisamment d'unités cachées

— Page 198, Apprentissage profond, 2016.

La modélisation prédictive de régression consiste à prédire une quantité numérique à partir d'entrées. La modélisation prédictive de classification implique la prédiction d’une étiquette de classe à partir d’entrées.

Ces deux problèmes de modélisation prédictive peuvent être considérés comme des exemples d’approximation de fonctions.

Pour rendre cela concret, nous pouvons passer en revue un exemple concret.

Dans la section suivante, définissons une fonction simple que nous pourrons ensuite approximer.

Définition d'une fonction simple

Nous pouvons définir une fonction simple avec une variable d'entrée numérique et une variable de sortie numérique et l'utiliser comme base pour comprendre les réseaux de neurones pour l'approximation des fonctions.

Nous pouvons définir un domaine de nombres comme entrée, comme des valeurs à virgule flottante de -50 à 50.

Nous pouvons ensuite sélectionner une opération mathématique à appliquer aux entrées pour obtenir les valeurs de sortie. L’opération mathématique sélectionnée sera la fonction de cartographie, et parce que nous la choisissons, nous saurons de quoi il s’agit. En pratique, ce n’est pas le cas et c’est la raison pour laquelle on utiliserait un algorithme d’apprentissage supervisé comme un réseau de neurones pour apprendre ou découvrir la fonction de cartographie.

Dans ce cas, nous utiliserons le carré de l’entrée comme fonction de mappage, définie comme :

  • y=x^2

y est la variable de sortie et x est la variable d'entrée.

Nous pouvons développer une intuition pour cette fonction de cartographie en énumérant les valeurs dans la plage de notre variable d'entrée, en calculant la valeur de sortie pour chaque entrée et en traçant le résultat.

L'exemple ci-dessous implémente cela en Python.

# example of creating a univariate dataset with a given mapping function
from matplotlib import pyplot
# define the input data
x = [i for i in range(-50,51)]
# define the output data
y = [i**2.0 for i in x]
# plot the input versus the output
pyplot.scatter(x,y)
pyplot.title('Input (x) versus Output (y)')
pyplot.xlabel('Input Variable (x)')
pyplot.ylabel('Output Variable (y)')
pyplot.show()

L’exécution de l’exemple crée d’abord une liste de valeurs entières sur l’ensemble du domaine d’entrée.

Les valeurs de sortie sont ensuite calculées à l'aide de la fonction de mappage, puis un tracé est créé avec les valeurs d'entrée sur l'axe des x et les valeurs de sortie sur l'axe des y.

Les variables d'entrée et de sortie représentent notre ensemble de données.

Ensuite, nous pouvons alors faire semblant d’oublier que nous savons ce qu’est la fonction de cartographie et utiliser un réseau de neurones pour réapprendre ou redécouvrir la fonction de cartographie.

Approximation d'une fonction simple

Nous pouvons adapter un modèle de réseau neuronal à des exemples d'entrées et de sorties et voir si le modèle peut apprendre la fonction de cartographie.

Il s’agit d’une fonction de cartographie très simple, nous nous attendons donc à ce qu’un petit réseau neuronal puisse l’apprendre rapidement.

Nous définirons le réseau à l'aide de la bibliothèque d'apprentissage en profondeur Keras et utiliserons certains outils de préparation de données de la bibliothèque scikit-learn.

Tout d’abord, définissons l’ensemble de données.

...
# define the dataset
x = asarray([i for i in range(-50,51)])
y = asarray([i**2.0 for i in x])
print(x.min(), x.max(), y.min(), y.max())

Ensuite, nous pouvons remodeler les données de manière à ce que les variables d'entrée et de sortie soient des colonnes avec une observation par ligne, comme on peut s'y attendre lors de l'utilisation de modèles d'apprentissage supervisé.

...
# reshape arrays into into rows and cols
x = x.reshape((len(x), 1))
y = y.reshape((len(y), 1))

Ensuite, nous devrons mettre à l’échelle les entrées et les sorties.

Les entrées auront une plage comprise entre -50 et 50, tandis que les sorties auront une plage comprise entre -50^2 (2500) et 0^2 (0). Des valeurs d'entrée et de sortie élevées peuvent rendre l'entraînement des réseaux neuronaux instables. C'est donc une bonne idée de commencer par mettre à l'échelle les données.

Nous pouvons utiliser MinMaxScaler pour normaliser séparément les valeurs d'entrée et les valeurs de sortie à des valeurs comprises entre 0 et 1.

...
# separately scale the input and output variables
scale_x = MinMaxScaler()
x = scale_x.fit_transform(x)
scale_y = MinMaxScaler()
y = scale_y.fit_transform(y)
print(x.min(), x.max(), y.min(), y.max())

Nous pouvons maintenant définir un modèle de réseau de neurones.

Après quelques essais et erreurs, j'ai choisi un modèle avec deux couches cachées et 10 nœuds dans chaque couche. Essayez peut-être d'autres configurations pour voir si vous pouvez faire mieux.

...
# design the neural network model
model = Sequential()
model.add(Dense(10, input_dim=1, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(10, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(1))

Nous ajusterons le modèle en utilisant une perte quadratique moyenne et utiliserons la version efficace d'Adam de la descente de gradient stochastique pour optimiser le modèle.

Cela signifie que le modèle cherchera à minimiser l'erreur quadratique moyenne entre les prédictions faites et les valeurs de sortie attendues (y) tout en essayant de se rapprocher de la fonction de cartographie.

...
# define the loss function and optimization algorithm
model.compile(loss='mse', optimizer='adam')

Nous n'avons pas beaucoup de données (par exemple environ 100 lignes), nous allons donc adapter le modèle à 500 époques et utiliser une petite taille de lot de 10.

Encore une fois, ces valeurs ont été trouvées après quelques essais et erreurs ; essayez différentes valeurs et voyez si vous pouvez faire mieux.

...
# ft the model on the training dataset
model.fit(x, y, epochs=500, batch_size=10, verbose=0)

Une fois ajusté, nous pouvons évaluer le modèle.

Nous ferons une prédiction pour chaque exemple de l'ensemble de données et calculerons l'erreur. Une approximation parfaite serait 0,0. Cela n'est généralement pas possible en raison du bruit dans les observations, des données incomplètes et de la complexité de la fonction de cartographie sous-jacente inconnue.

Dans ce cas, c’est possible car nous disposons de toutes les observations, il n’y a pas de bruit dans les données et la fonction sous-jacente n’est pas complexe.

Premièrement, nous pouvons faire la prédiction.

...
# make predictions for the input data
yhat = model.predict(x)

Nous devons alors inverser la mise à l'échelle que nous avons effectuée.

Ainsi, l'erreur est signalée dans les unités d'origine de la variable cible.

...
# inverse transforms
x_plot = scale_x.inverse_transform(x)
y_plot = scale_y.inverse_transform(y)
yhat_plot = scale_y.inverse_transform(yhat)

Nous pouvons ensuite calculer et rapporter l'erreur de prédiction dans les unités d'origine de la variable cible.

...
# report model error
print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot))

Enfin, nous pouvons créer un nuage de points du mappage réel des entrées aux sorties et le comparer au mappage des entrées aux sorties prédites et voir à quoi ressemble l'approximation de la fonction de mappage dans l'espace.

Ceci est utile pour développer l’intuition derrière ce que les réseaux neuronaux apprennent.

...
# plot x vs yhat
pyplot.scatter(x_plot,yhat_plot, label='Predicted')
pyplot.title('Input (x) versus Output (y)')
pyplot.xlabel('Input Variable (x)')
pyplot.ylabel('Output Variable (y)')
pyplot.legend()
pyplot.show()

En reliant cela ensemble, l’exemple complet est répertorié ci-dessous.

# example of fitting a neural net on x vs x^2
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import mean_squared_error
from keras.models import Sequential
from keras.layers import Dense
from numpy import asarray
from matplotlib import pyplot
# define the dataset
x = asarray([i for i in range(-50,51)])
y = asarray([i**2.0 for i in x])
print(x.min(), x.max(), y.min(), y.max())
# reshape arrays into into rows and cols
x = x.reshape((len(x), 1))
y = y.reshape((len(y), 1))
# separately scale the input and output variables
scale_x = MinMaxScaler()
x = scale_x.fit_transform(x)
scale_y = MinMaxScaler()
y = scale_y.fit_transform(y)
print(x.min(), x.max(), y.min(), y.max())
# design the neural network model
model = Sequential()
model.add(Dense(10, input_dim=1, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(10, activation='relu', kernel_initializer='he_uniform'))
model.add(Dense(1))
# define the loss function and optimization algorithm
model.compile(loss='mse', optimizer='adam')
# ft the model on the training dataset
model.fit(x, y, epochs=500, batch_size=10, verbose=0)
# make predictions for the input data
yhat = model.predict(x)
# inverse transforms
x_plot = scale_x.inverse_transform(x)
y_plot = scale_y.inverse_transform(y)
yhat_plot = scale_y.inverse_transform(yhat)
# report model error
print('MSE: %.3f' % mean_squared_error(y_plot, yhat_plot))
# plot x vs y
pyplot.scatter(x_plot,y_plot, label='Actual')
# plot x vs yhat
pyplot.scatter(x_plot,yhat_plot, label='Predicted')
pyplot.title('Input (x) versus Output (y)')
pyplot.xlabel('Input Variable (x)')
pyplot.ylabel('Output Variable (y)')
pyplot.legend()
pyplot.show()

L'exécution de l'exemple indique d'abord la plage de valeurs des variables d'entrée et de sortie, puis la plage des mêmes variables après la mise à l'échelle. Cela confirme que l’opération de mise à l’échelle a été effectuée comme prévu.

Le modèle est ensuite ajusté et évalué sur l'ensemble de données.

Remarque : Vos résultats peuvent varier en raison de la nature stochastique de l'algorithme ou de la procédure d'évaluation, ou des différences de précision numérique. Pensez à exécuter l’exemple plusieurs fois et comparez le résultat moyen.

Dans ce cas, nous pouvons voir que l’erreur quadratique moyenne est d’environ 1 300, en unités carrées. Si nous calculons la racine carrée, cela nous donne l’erreur quadratique moyenne (RMSE) dans les unités d’origine. Nous pouvons voir que l’erreur moyenne est d’environ 36 unités, ce qui est bien, mais pas génial.

Quels résultats avez-vous obtenus ? Pouvez-vous faire mieux ?
Faites-le moi savoir dans les commentaires ci-dessous.

-50 50 0.0 2500.0
0.0 1.0 0.0 1.0
MSE: 1300.776

Un nuage de points est ensuite créé comparant les entrées aux sorties réelles et les entrées aux sorties prédites.

La différence entre ces deux séries de données réside dans l'erreur d'approximation de la fonction de cartographie. On voit que l’approximation est raisonnable ; il capture la forme générale. Nous pouvons voir qu'il y a des erreurs, notamment autour des valeurs d'entrée 0.

Cela suggère qu'il existe de nombreuses possibilités d'amélioration, comme l'utilisation d'une fonction d'activation différente ou d'une architecture de réseau différente pour mieux se rapprocher de la fonction de mappage.

Lectures complémentaires

Cette section fournit plus de ressources sur le sujet si vous souhaitez approfondir.

Tutoriels

  • Votre premier projet de Deep Learning en Python avec Keras étape par étape

Livres

  • Apprentissage profond, 2016.

Articles

  • Approximation des fonctions, Wikipédia.

Résumé

Dans ce didacticiel, vous avez découvert l'intuition qui se cache derrière les réseaux de neurones en tant qu'algorithmes d'approximation de fonctions.

Concrètement, vous avez appris :

  • La formation d'un réseau neuronal sur des données se rapproche de la fonction de cartographie sous-jacente inconnue des entrées aux sorties.
  • Les ensembles de données d'entrée et de sortie unidimensionnelles fournissent une base utile pour développer les intuitions de l'approximation des fonctions.
  • Comment développer et évaluer un petit réseau neuronal pour l'approximation des fonctions.

Avez-vous des questions ?
Posez vos questions dans les commentaires ci-dessous et je ferai de mon mieux pour y répondre.

Articles connexes