Recherche de site Web

Comment utiliser l'API fonctionnelle Keras pour le Deep Learning


La bibliothèque Keras Python permet de créer des modèles d'apprentissage en profondeur rapidement et facilement.

L'API séquentielle vous permet de créer des modèles couche par couche pour la plupart des problèmes. Il est limité dans le sens où il ne vous permet pas de créer des modèles partageant des couches ou comportant plusieurs entrées ou sorties.

L'API fonctionnelle de Keras est une autre manière de créer des modèles qui offre beaucoup plus de flexibilité, notamment la création de modèles plus complexes.

Dans ce tutoriel, vous découvrirez comment utiliser l'API fonctionnelle plus flexible de Keras pour définir des modèles d'apprentissage en profondeur.

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

  • La différence entre les API séquentielles et fonctionnelles.
  • Comment définir des modèles simples de Perceptron multicouche, de réseau neuronal convolutif et de réseau neuronal récurrent à l'aide de l'API fonctionnelle.
  • Comment définir des modèles plus complexes avec des couches partagées et plusieurs entrées et sorties.

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.

  • Mise à jour de novembre 2017 : ajout d'une remarque sur les dimensions suspendues pour les calques en entrée.
  • Mise à jour de novembre 2018 : ajout d'une couche d'aplatissement manquante pour CNN, merci Konstantin.
  • Mise à jour novembre/2018 : ajout d'une description de la syntaxe fonctionnelle de l'API Python.

Présentation du didacticiel

Ce tutoriel est divisé en 7 parties ; ils sont:

  1. Modèles séquentiels Keras
  2. Modèles fonctionnels Keras
  3. Modèles de réseau standards
  4. Modèle de couches partagées
  5. Plusieurs modèles d'entrée et de sortie
  6. Meilleures pratiques
  7. NOUVEAU : Remarque sur la syntaxe Python de l'API fonctionnelle

1. Modèles séquentiels Keras

En guise de révision, Keras fournit une API de modèle séquentiel.

Si vous êtes nouveau sur Keras ou sur l'apprentissage en profondeur, consultez ce didacticiel Keras étape par étape.

L'API du modèle Sequential est un moyen de créer des modèles d'apprentissage en profondeur dans lesquels une instance de la classe Sequential est créée et des couches de modèle sont créées et ajoutées à celle-ci.

Par exemple, les couches peuvent être définies et transmises au Sequential sous forme de tableau :

from keras.models import Sequential
from keras.layers import Dense
model = Sequential([Dense(2, input_dim=1), Dense(1)])

Les calques peuvent également être ajoutés par morceaux :

from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(2, input_dim=1))
model.add(Dense(1))

L'API du modèle séquentiel est idéale pour développer des modèles d'apprentissage en profondeur dans la plupart des situations, mais elle présente également certaines limites.

Par exemple, il n’est pas simple de définir des modèles pouvant avoir plusieurs sources d’entrée différentes, produire plusieurs destinations de sortie ou des modèles réutilisant des couches.

2. Modèles fonctionnels Keras

L'API fonctionnelle Keras offre un moyen plus flexible de définir des modèles.

Il vous permet spécifiquement de définir plusieurs modèles d'entrée ou de sortie ainsi que des modèles partageant des couches. De plus, il vous permet de définir des graphiques de réseau acycliques ad hoc.

Les modèles sont définis en créant des instances de couches et en les connectant directement les unes aux autres par paires, puis en définissant un modèle qui spécifie les couches devant servir d'entrée et de sortie au modèle.

Examinons tour à tour les trois aspects uniques de l'API fonctionnelle Keras :

1. Définir l'entrée

Contrairement au modèle séquentiel, vous devez créer et définir une couche d'entrée autonome qui spécifie la forme des données d'entrée.

La couche d'entrée prend un argument de forme qui est un tuple qui indique la dimensionnalité des données d'entrée.

Lorsque les données d'entrée sont unidimensionnelles, comme pour un Perceptron multicouche, la forme doit explicitement laisser de la place à la forme de la taille du mini-lot utilisée lors de la division des données lors de la formation du réseau. Par conséquent, le tuple de forme est toujours défini avec une dernière dimension suspendue lorsque l'entrée est unidimensionnelle (2,), par exemple :

from keras.layers import Input
visible = Input(shape=(2,))

2. Connexion des couches

Les couches du modèle sont connectées par paires.

Cela se fait en spécifiant d'où provient l'entrée lors de la définition de chaque nouveau calque. Une notation entre crochets est utilisée, de sorte qu'après la création du calque, le calque d'où provient l'entrée du calque actuel est spécifié.

Soyons clairs avec un court exemple. Nous pouvons créer la couche d'entrée comme ci-dessus, puis créer une couche cachée en tant que Dense qui reçoit uniquement les entrées de la couche d'entrée.

from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(2,))
hidden = Dense(2)(visible)

Notez le (visible) après la création de la couche dense qui connecte la sortie de la couche d'entrée comme entrée à la couche cachée dense.

C’est cette façon de connecter les couches pièce par pièce qui donne à l’API fonctionnelle sa flexibilité. Par exemple, vous pouvez voir à quel point il serait facile de commencer à définir des graphiques ad hoc de couches.

3. Création du modèle

Après avoir créé toutes vos couches de modèle et les avoir connectées entre elles, vous devez définir le modèle.

Comme pour l'API Sequential, le modèle est l'élément que vous pouvez résumer, ajuster, évaluer et utiliser pour faire des prédictions.

Keras fournit une classe Model que vous pouvez utiliser pour créer un modèle à partir de vos calques créés. Cela nécessite que vous spécifiiez uniquement les couches d’entrée et de sortie. Par exemple:

from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(2,))
hidden = Dense(2)(visible)
model = Model(inputs=visible, outputs=hidden)

Maintenant que nous connaissons tous les éléments clés de l'API fonctionnelle Keras, passons à la définition d'une suite de différents modèles et développons une certaine pratique avec.

Chaque exemple est exécutable et imprime la structure et crée un diagramme du graphique. Je recommande de faire cela pour vos propres modèles afin de préciser clairement ce que vous avez défini exactement.

J'espère que ces exemples vous fourniront des modèles lorsque vous souhaiterez définir vos propres modèles à l'aide de l'API fonctionnelle à l'avenir.

3. Modèles de réseau standard

Lorsque vous débutez avec l'API fonctionnelle, c'est une bonne idée de voir comment sont définis certains modèles de réseaux neuronaux standard.

Dans cette section, nous examinerons la définition d'un Perceptron multicouche simple, d'un réseau neuronal convolutif et d'un réseau neuronal récurrent.

Ces exemples fourniront une base pour comprendre ultérieurement les exemples plus élaborés.

Perceptron multicouche

Dans cette section, nous définissons un modèle Perceptron multicouche pour la classification binaire.

Le modèle comporte 10 entrées, 3 couches cachées avec 10, 20 et 10 neurones et une couche de sortie avec 1 sortie. Des fonctions d'activation linéaire rectifiées sont utilisées dans chaque couche cachée et une fonction d'activation sigmoïde est utilisée dans la couche de sortie, pour la classification binaire.

# Multilayer Perceptron
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
visible = Input(shape=(10,))
hidden1 = Dense(10, activation='relu')(visible)
hidden2 = Dense(20, activation='relu')(hidden1)
hidden3 = Dense(10, activation='relu')(hidden2)
output = Dense(1, activation='sigmoid')(hidden3)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multilayer_perceptron_graph.png')

L’exécution de l’exemple imprime la structure du réseau.

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_1 (InputLayer)         (None, 10)                0
_________________________________________________________________
dense_1 (Dense)              (None, 10)                110
_________________________________________________________________
dense_2 (Dense)              (None, 20)                220
_________________________________________________________________
dense_3 (Dense)              (None, 10)                210
_________________________________________________________________
dense_4 (Dense)              (None, 1)                 11
=================================================================
Total params: 551
Trainable params: 551
Non-trainable params: 0
_________________________________________________________________

Un tracé du graphique du modèle est également créé et enregistré dans un fichier.

Réseau neuronal convolutif

Dans cette section, nous définirons un réseau de neurones convolutifs pour la classification d'images.

Le modèle reçoit des images 64 × 64 en noir et blanc en entrée, puis comporte une séquence de deux couches convolutives et de regroupement comme extracteurs de caractéristiques, suivie d'une couche entièrement connectée pour interpréter les caractéristiques et d'une couche de sortie avec une activation sigmoïde pour les prédictions à deux classes. .

# Convolutional Neural Network
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
visible = Input(shape=(64,64,1))
conv1 = Conv2D(32, kernel_size=4, activation='relu')(visible)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
conv2 = Conv2D(16, kernel_size=4, activation='relu')(pool1)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
flat = Flatten()(pool2)
hidden1 = Dense(10, activation='relu')(flat)
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='convolutional_neural_network.png')

L’exécution de l’exemple résume les couches du modèle.

_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
input_1 (InputLayer)         (None, 64, 64, 1)         0         
_________________________________________________________________
conv2d_1 (Conv2D)            (None, 61, 61, 32)        544       
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 30, 30, 32)        0         
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 27, 27, 16)        8208      
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 13, 13, 16)        0         
_________________________________________________________________
flatten_1 (Flatten)          (None, 2704)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 10)                27050     
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 11        
=================================================================
Total params: 35,813
Trainable params: 35,813
Non-trainable params: 0
_________________________________________________________________

Un tracé du graphique du modèle est également créé et enregistré dans un fichier.

Réseau neuronal récurrent

Dans cette section, nous définirons un réseau neuronal récurrent à mémoire à long terme et à court terme pour la classification des séquences.

Le modèle attend 100 pas de temps d'une fonctionnalité en entrée. Le modèle comporte une seule couche cachée LSTM pour extraire les caractéristiques de la séquence, suivie d'une couche entièrement connectée pour interpréter la sortie LSTM, suivie d'une couche de sortie pour effectuer des prédictions binaires.

# Recurrent Neural Network
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
visible = Input(shape=(100,1))
hidden1 = LSTM(10)(visible)
hidden2 = Dense(10, activation='relu')(hidden1)
output = Dense(1, activation='sigmoid')(hidden2)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='recurrent_neural_network.png')

L’exécution de l’exemple résume les couches du modèle.

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
input_1 (InputLayer)         (None, 100, 1)            0
_________________________________________________________________
lstm_1 (LSTM)                (None, 10)                480
_________________________________________________________________
dense_1 (Dense)              (None, 10)                110
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 11
=================================================================
Total params: 601
Trainable params: 601
Non-trainable params: 0
_________________________________________________________________

Un tracé du graphique du modèle est également créé et enregistré dans un fichier.

4. Modèle de couches partagées

Plusieurs couches peuvent partager la sortie d’une seule couche.

Par exemple, il peut y avoir plusieurs couches d'extraction de fonctionnalités différentes à partir d'une entrée, ou plusieurs couches utilisées pour interpréter la sortie d'une couche d'extraction de fonctionnalités.

Examinons ces deux exemples.

Couche d'entrée partagée

Dans cette section, nous définissons plusieurs couches convolutives avec des noyaux de tailles différentes pour interpréter une entrée d'image.

Le modèle prend des images en noir et blanc de 64 × 64 pixels. Il existe deux sous-modèles d'extraction de fonctionnalités CNN qui partagent cette entrée ; le premier a une taille de noyau de 4 et le second une taille de noyau de 8. Les sorties de ces sous-modèles d'extraction de fonctionnalités sont aplaties en vecteurs et concaténées en un long vecteur et transmises à une couche entièrement connectée pour interprétation avant qu'une couche de sortie finale ne fasse une classification binaire.

# Shared Input Layer
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
# input layer
visible = Input(shape=(64,64,1))
# first feature extractor
conv1 = Conv2D(32, kernel_size=4, activation='relu')(visible)
pool1 = MaxPooling2D(pool_size=(2, 2))(conv1)
flat1 = Flatten()(pool1)
# second feature extractor
conv2 = Conv2D(16, kernel_size=8, activation='relu')(visible)
pool2 = MaxPooling2D(pool_size=(2, 2))(conv2)
flat2 = Flatten()(pool2)
# merge feature extractors
merge = concatenate([flat1, flat2])
# interpretation layer
hidden1 = Dense(10, activation='relu')(merge)
# prediction output
output = Dense(1, activation='sigmoid')(hidden1)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='shared_input_layer.png')

L’exécution de l’exemple résume les couches du modèle.

____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to
====================================================================================================
input_1 (InputLayer)             (None, 64, 64, 1)     0
____________________________________________________________________________________________________
conv2d_1 (Conv2D)                (None, 61, 61, 32)    544         input_1[0][0]
____________________________________________________________________________________________________
conv2d_2 (Conv2D)                (None, 57, 57, 16)    1040        input_1[0][0]
____________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)   (None, 30, 30, 32)    0           conv2d_1[0][0]
____________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)   (None, 28, 28, 16)    0           conv2d_2[0][0]
____________________________________________________________________________________________________
flatten_1 (Flatten)              (None, 28800)         0           max_pooling2d_1[0][0]
____________________________________________________________________________________________________
flatten_2 (Flatten)              (None, 12544)         0           max_pooling2d_2[0][0]
____________________________________________________________________________________________________
concatenate_1 (Concatenate)      (None, 41344)         0           flatten_1[0][0]
                                                                   flatten_2[0][0]
____________________________________________________________________________________________________
dense_1 (Dense)                  (None, 10)            413450      concatenate_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense)                  (None, 1)             11          dense_1[0][0]
====================================================================================================
Total params: 415,045
Trainable params: 415,045
Non-trainable params: 0
____________________________________________________________________________________________________

Un tracé du graphique du modèle est également créé et enregistré dans un fichier.

Couche d'extraction de fonctionnalités partagée

Dans cette section, nous utiliserons deux sous-modèles parallèles pour interpréter la sortie d'un extracteur de fonctionnalités LSTM pour la classification de séquences.

L'entrée dans le modèle est de 100 pas de temps d'une fonctionnalité. Une couche LSTM avec 10 cellules mémoire interprète cette séquence. Le premier modèle d’interprétation est une couche unique peu profonde entièrement connectée, le second est un modèle profond à 3 couches. Les sorties des deux modèles d'interprétation sont concaténées en un seul long vecteur qui est transmis à la couche de sortie utilisée pour effectuer une prédiction binaire.

# Shared Feature Extraction Layer
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
from keras.layers.merge import concatenate
# define input
visible = Input(shape=(100,1))
# feature extraction
extract1 = LSTM(10)(visible)
# first interpretation model
interp1 = Dense(10, activation='relu')(extract1)
# second interpretation model
interp11 = Dense(10, activation='relu')(extract1)
interp12 = Dense(20, activation='relu')(interp11)
interp13 = Dense(10, activation='relu')(interp12)
# merge interpretation
merge = concatenate([interp1, interp13])
# output
output = Dense(1, activation='sigmoid')(merge)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='shared_feature_extractor.png')

L’exécution de l’exemple résume les couches du modèle.

____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to
====================================================================================================
input_1 (InputLayer)             (None, 100, 1)        0
____________________________________________________________________________________________________
lstm_1 (LSTM)                    (None, 10)            480         input_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense)                  (None, 10)            110         lstm_1[0][0]
____________________________________________________________________________________________________
dense_3 (Dense)                  (None, 20)            220         dense_2[0][0]
____________________________________________________________________________________________________
dense_1 (Dense)                  (None, 10)            110         lstm_1[0][0]
____________________________________________________________________________________________________
dense_4 (Dense)                  (None, 10)            210         dense_3[0][0]
____________________________________________________________________________________________________
concatenate_1 (Concatenate)      (None, 20)            0           dense_1[0][0]
                                                                   dense_4[0][0]
____________________________________________________________________________________________________
dense_5 (Dense)                  (None, 1)             21          concatenate_1[0][0]
====================================================================================================
Total params: 1,151
Trainable params: 1,151
Non-trainable params: 0
____________________________________________________________________________________________________

Un tracé du graphique du modèle est également créé et enregistré dans un fichier.

5. Plusieurs modèles d'entrée et de sortie

L'API fonctionnelle peut également être utilisée pour développer des modèles plus complexes avec plusieurs entrées, éventuellement avec différentes modalités. Il peut également être utilisé pour développer des modèles produisant plusieurs résultats.

Nous examinerons des exemples de chacun dans cette section.

Modèle à entrées multiples

Nous développerons un modèle de classification d'images qui prend en entrée deux versions de l'image, chacune d'une taille différente. Plus précisément une version noir et blanc 64×64 et une version couleur 32×32. Des modèles CNN d'extraction de caractéristiques distincts fonctionnent sur chacun, puis les résultats des deux modèles sont concaténés pour l'interprétation et la prédiction finale.

Notez que lors de la création de l’instance Model(), nous définissons les deux couches d’entrée sous forme de tableau. Spécifiquement:

model = Model(inputs=[visible1, visible2], outputs=output)

L’exemple complet est répertorié ci-dessous.

# Multiple Inputs
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers import Flatten
from keras.layers.convolutional import Conv2D
from keras.layers.pooling import MaxPooling2D
from keras.layers.merge import concatenate
# first input model
visible1 = Input(shape=(64,64,1))
conv11 = Conv2D(32, kernel_size=4, activation='relu')(visible1)
pool11 = MaxPooling2D(pool_size=(2, 2))(conv11)
conv12 = Conv2D(16, kernel_size=4, activation='relu')(pool11)
pool12 = MaxPooling2D(pool_size=(2, 2))(conv12)
flat1 = Flatten()(pool12)
# second input model
visible2 = Input(shape=(32,32,3))
conv21 = Conv2D(32, kernel_size=4, activation='relu')(visible2)
pool21 = MaxPooling2D(pool_size=(2, 2))(conv21)
conv22 = Conv2D(16, kernel_size=4, activation='relu')(pool21)
pool22 = MaxPooling2D(pool_size=(2, 2))(conv22)
flat2 = Flatten()(pool22)
# merge input models
merge = concatenate([flat1, flat2])
# interpretation model
hidden1 = Dense(10, activation='relu')(merge)
hidden2 = Dense(10, activation='relu')(hidden1)
output = Dense(1, activation='sigmoid')(hidden2)
model = Model(inputs=[visible1, visible2], outputs=output)
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multiple_inputs.png')

L’exécution de l’exemple résume les couches du modèle.

____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to
====================================================================================================
input_1 (InputLayer)             (None, 64, 64, 1)     0
____________________________________________________________________________________________________
input_2 (InputLayer)             (None, 32, 32, 3)     0
____________________________________________________________________________________________________
conv2d_1 (Conv2D)                (None, 61, 61, 32)    544         input_1[0][0]
____________________________________________________________________________________________________
conv2d_3 (Conv2D)                (None, 29, 29, 32)    1568        input_2[0][0]
____________________________________________________________________________________________________
max_pooling2d_1 (MaxPooling2D)   (None, 30, 30, 32)    0           conv2d_1[0][0]
____________________________________________________________________________________________________
max_pooling2d_3 (MaxPooling2D)   (None, 14, 14, 32)    0           conv2d_3[0][0]
____________________________________________________________________________________________________
conv2d_2 (Conv2D)                (None, 27, 27, 16)    8208        max_pooling2d_1[0][0]
____________________________________________________________________________________________________
conv2d_4 (Conv2D)                (None, 11, 11, 16)    8208        max_pooling2d_3[0][0]
____________________________________________________________________________________________________
max_pooling2d_2 (MaxPooling2D)   (None, 13, 13, 16)    0           conv2d_2[0][0]
____________________________________________________________________________________________________
max_pooling2d_4 (MaxPooling2D)   (None, 5, 5, 16)      0           conv2d_4[0][0]
____________________________________________________________________________________________________
flatten_1 (Flatten)              (None, 2704)          0           max_pooling2d_2[0][0]
____________________________________________________________________________________________________
flatten_2 (Flatten)              (None, 400)           0           max_pooling2d_4[0][0]
____________________________________________________________________________________________________
concatenate_1 (Concatenate)      (None, 3104)          0           flatten_1[0][0]
                                                                   flatten_2[0][0]
____________________________________________________________________________________________________
dense_1 (Dense)                  (None, 10)            31050       concatenate_1[0][0]
____________________________________________________________________________________________________
dense_2 (Dense)                  (None, 10)            110         dense_1[0][0]
____________________________________________________________________________________________________
dense_3 (Dense)                  (None, 1)             11          dense_2[0][0]
====================================================================================================
Total params: 49,699
Trainable params: 49,699
Non-trainable params: 0
____________________________________________________________________________________________________

Un tracé du graphique du modèle est également créé et enregistré dans un fichier.

Modèle de sortie multiple

Dans cette section, nous développerons un modèle qui effectue deux types différents de prédictions. Étant donné une séquence d'entrée de 100 pas de temps d'une caractéristique, le modèle classera la séquence et générera une nouvelle séquence de même longueur.

Une couche LSTM interprète la séquence d'entrée et renvoie l'état caché pour chaque pas de temps. Le premier modèle de sortie crée un LSTM empilé, interprète les caractéristiques et effectue une prédiction binaire. Le deuxième modèle de sortie utilise la même couche de sortie pour effectuer une prédiction à valeur réelle pour chaque pas de temps d'entrée.

# Multiple Outputs
from keras.utils import plot_model
from keras.models import Model
from keras.layers import Input
from keras.layers import Dense
from keras.layers.recurrent import LSTM
from keras.layers.wrappers import TimeDistributed
# input layer
visible = Input(shape=(100,1))
# feature extraction
extract = LSTM(10, return_sequences=True)(visible)
# classification output
class11 = LSTM(10)(extract)
class12 = Dense(10, activation='relu')(class11)
output1 = Dense(1, activation='sigmoid')(class12)
# sequence output
output2 = TimeDistributed(Dense(1, activation='linear'))(extract)
# output
model = Model(inputs=visible, outputs=[output1, output2])
# summarize layers
print(model.summary())
# plot graph
plot_model(model, to_file='multiple_outputs.png')

L’exécution de l’exemple résume les couches du modèle.

____________________________________________________________________________________________________
Layer (type)                     Output Shape          Param #     Connected to
====================================================================================================
input_1 (InputLayer)             (None, 100, 1)        0
____________________________________________________________________________________________________
lstm_1 (LSTM)                    (None, 100, 10)       480         input_1[0][0]
____________________________________________________________________________________________________
lstm_2 (LSTM)                    (None, 10)            840         lstm_1[0][0]
____________________________________________________________________________________________________
dense_1 (Dense)                  (None, 10)            110         lstm_2[0][0]
____________________________________________________________________________________________________
dense_2 (Dense)                  (None, 1)             11          dense_1[0][0]
____________________________________________________________________________________________________
time_distributed_1 (TimeDistribu (None, 100, 1)        11          lstm_1[0][0]
====================================================================================================
Total params: 1,452
Trainable params: 1,452
Non-trainable params: 0
____________________________________________________________________________________________________

Un tracé du graphique du modèle est également créé et enregistré dans un fichier.

6. Meilleures pratiques

Dans cette section, je souhaite vous donner quelques conseils pour tirer le meilleur parti de l'API fonctionnelle lorsque vous définissez vos propres modèles.

  • Noms de variables cohérents. Utilisez le même nom de variable pour les couches d'entrée (visible) et de sortie (output) et peut-être même pour les couches cachées (hidden1, Hidden2). Cela aidera à relier les choses correctement.
  • Résumé de la couche de révision. Imprimez toujours le résumé du modèle et examinez les sorties des couches pour vous assurer que le modèle a été connecté comme prévu.
  • Examiner les tracés graphiques. Créez toujours un tracé du graphique du modèle et examinez-le pour vous assurer que tout a été assemblé comme vous le souhaitiez.
  • Nommez les calques. Vous pouvez attribuer des noms aux couches utilisées lors de la révision des résumés et des tracés du graphique du modèle. Par exemple : Dense(1, name=’hidden1′).
  • Sous-modèles séparés. Envisagez de séparer le développement des sous-modèles et de combiner les sous-modèles ensemble à la fin.

Avez-vous vos propres conseils en matière de bonnes pratiques lors de l'utilisation de l'API fonctionnelle ?
Faites-le moi savoir dans les commentaires.

7. Remarque sur la syntaxe Python de l'API fonctionnelle

Si vous êtes nouveau ou novice en Python, la syntaxe utilisée dans l'API fonctionnelle peut prêter à confusion.

Par exemple, étant donné :

...
dense1 = Dense(32)(input)
...

À quoi sert la syntaxe à double crochet ?

Qu'est-ce que cela signifie ?

Cela semble déroutant, mais ce n'est pas une chose spéciale pour Python, juste une ligne faisant deux choses.

La première parenthèse « (32) » crée la couche via le constructeur de classe, la deuxième parenthèse « (input) » est une fonction sans nom implémentée via le Fonction __call__() qui, une fois appelée, connectera les couches.

La fonction __call__() est une fonction par défaut sur tous les objets Python qui peut être remplacée et est utilisée pour « appeler » un objet instancié. Tout comme la fonction __init__() est une fonction par défaut sur tous les objets appelée juste après l'instanciation d'un objet pour l'initialiser.

On peut faire la même chose en deux lignes :

# create layer
dense1 = Dense(32)
# connect layer to previous layer
dense1(input)

Je suppose que nous pourrions également appeler explicitement la fonction __call__() sur l'objet, même si je n'ai jamais essayé :

# create layer
dense1 = Dense(32)
# connect layer to previous layer
dense1.__call_(input)

Lectures complémentaires

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

  • L'API du modèle séquentiel
  • Premiers pas avec le modèle Keras Sequential
  • Premiers pas avec l'API fonctionnelle Keras
  • Classe de modèle API fonctionnelle

Résumé

Dans ce didacticiel, vous avez découvert comment utiliser l'API fonctionnelle de Keras pour définir des modèles d'apprentissage profond simples et complexes.

Concrètement, vous avez appris :

  • La différence entre les API séquentielles et fonctionnelles.
  • Comment définir des modèles simples de Perceptron multicouche, de réseau neuronal convolutif et de réseau neuronal récurrent à l'aide de l'API fonctionnelle.
  • Comment définir des modèles plus complexes avec des couches partagées et plusieurs entrées et sorties.

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

Articles connexes