Pour ceux qui veulent essayer ceci ou cela pour la modélisation du deep learning mais ne savent pas comment l'implémenter Utiliser l'API fonctionnelle de Keras comme un framework relativement flexible et raisonnablement abstrait Essayez d'implémenter seq2seq, ce qui est difficile avec séquentiel, aussi simplement que possible
Il s'avère que les keras peuvent être utilisés pour mettre en œuvre un apprentissage en profondeur. Quel type de code dois-je écrire spécifiquement? Je vais répondre à la question.
Lors de l'utilisation de keras, il est pratique d'utiliser la classe Model. https://keras.io/ja/models/model/
La classe Model
est responsable de la définition des méthodes d'apprentissage, de l'exécution de l'apprentissage et de la déduction dans un modèle déterminé par l'apprentissage.
Afin de créer une instance Model
, il est nécessaire de créer au préalable un graphique de calcul pour le modèle d'apprentissage automatique.
Il existe deux options pour cela: une API séquentielle et une API fonctionnelle.
L'API séquentielle est très simple et est utile lorsque le traitement de la couche précédente devient le traitement de la couche suivante telle quelle.
Au lieu de cela, il sacrifie la flexibilité du modèle et ne peut pas être utilisé avec une complexité croissante, comme les modèles multi-entrées et multi-sorties.
Par rapport à l'API séquentielle, l'API fonctionnelle vous oblige à définir vous-même la connexion entre les couches, mais vous pouvez l'écrire de manière plus flexible.
Cette fois, nous allons créer un modèle à l'aide de l'API fonctionnelle.
Une fois que vous avez construit un graphe de calcul et créé une instance Model
, le reste est facile
Définition de la méthode d'apprentissage avec la méthode compile
de l'instance Model
(méthode d'optimisation, réglage de la fonction de perte, etc.)
Vous pouvez exécuter l'apprentissage avec la méthode fit
.
Nous allons construire le modèle montré dans la figure suivante
Il y a deux choses à faire avec l'encodeur: incorporer l'entrée et entrer dans le LSTM. L'exemple de mise en œuvre est le suivant
from keras.layers import Input, LSTM, Dense, Embedding
# Define an input sequence and process it.
encoder_inputs = Input(shape=(max_length_inp,),name='encoder_input')
encoder_inputs_embedding = Embedding(input_dim=vocab_inp_size, output_dim=embedding_dim)(encoder_inputs)
encoder = LSTM(units, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs_embedding)
# We discard `encoder_outputs` and only keep the states.
encoder_states = [state_h, state_c]
L'entrée dans le modèle se fait toujours à partir de la couche ʻInput. Ici, à partir de ʻInput
, les données de la dimension de longueur maximale max_length_inp
de la chaîne de caractères d'entrée sont entrées en même temps.
L'algorithme basé sur RNN traite les chaînes de données d'entrée une par une et les transmet à l'étape suivante dans l'ordre, mais il peut également être abrégé de cette manière.
encoder_inputs_embedding = Embedding(input_dim=vocab_inp_size, output_dim=embedding_dim)(encoder_inputs)
Veux dire
"Définissez la couche ʻEmbedding avec ʻinput_dim = vocal_inp_size, output_dim = embedding_dim
"
"Ajoutez un graphe de calcul de sorte que le résultat de la substitution de ʻencoder_inputs par ʻEmbedding
défini soit ʻencoder_inputs_embedding`"
Cela signifie que.
encoder = LSTM(units, return_state=True)
encoder_outputs, state_h, state_c = encoder(encoder_inputs_embedding)
Vous pouvez également définir la couche et l'ajouter au graphique de calcul sur une ligne distincte, comme dans.
Il y a trois choses à faire avec le décodeur: l'incorporation (pour forcer l'enseignant), LSTM et Dense pour l'entrée du décodeur. L'exemple de mise en œuvre est le suivant
from keras.layers import Input, LSTM, Dense, Embedding
# Set up the decoder, using `encoder_states` as initial state.
decoder_inputs = Input(shape=(max_length_targ-1,),name='decoder_input')
decoder_inputs_embedding = Embedding(input_dim=vocab_tar_size, output_dim=embedding_dim)(decoder_inputs)
# We set up our decoder to return full output sequences,
# and to return internal states as well. We don't use the
# return states in the training model, but we will use them in inference.
decoder_lstm = LSTM(units, return_sequences=True, return_state=True)
decoder_outputs, _, _ = decoder_lstm(decoder_inputs_embedding,
initial_state=encoder_states)
decoder_dense = Dense(vocab_tar_size, activation='softmax')
decoder_outputs = decoder_dense(decoder_outputs)
Qu'est-ce qui est différent de l'encodeur
a une forme de moins
.return_sequences = True
de LSTM
pour obtenir la sortie LSTM
pour chaque étapeLSTM
reçoit la mémoire de couche cachée LSTM
ʻencoder_states` obtenue de l'encodeurSi vous arrivez à ce point, le reste est simple
from keras.models import Model
# Define the model that will turn
# `encoder_input_data` & `decoder_input_data` into `decoder_target_data`
model = Model([encoder_inputs, decoder_inputs], decoder_outputs)
from IPython.display import SVG
SVG(model_to_dot(model).create(prog='dot', format='svg'))
Vous pouvez visualiser le graphique de calcul qui représente le modèle avec.
La relation de position du dessin de chaque couche est différente de la figure montrée au début, mais vous pouvez voir que c'est la même chose qu'un réseau.
Aussi,
model.summary()
Vous pouvez vérifier le nombre de paramètres pour chaque couche avec.
__________________________________________________________________________________________________
Layer (type) Output Shape Param # Connected to
==================================================================================================
encoder_input (InputLayer) (None, 18) 0
__________________________________________________________________________________________________
decoder_input (InputLayer) (None, 17) 0
__________________________________________________________________________________________________
embedding_1 (Embedding) (None, 18, 256) 1699328 encoder_input[0][0]
__________________________________________________________________________________________________
embedding_2 (Embedding) (None, 17, 256) 2247168 decoder_input[0][0]
__________________________________________________________________________________________________
lstm_1 (LSTM) [(None, 1024), (None 5246976 embedding_1[0][0]
__________________________________________________________________________________________________
lstm_2 (LSTM) [(None, 17, 1024), ( 5246976 embedding_2[0][0]
lstm_1[0][1]
lstm_1[0][2]
__________________________________________________________________________________________________
dense_1 (Dense) (None, 17, 8778) 8997450 lstm_2[0][0]
==================================================================================================
Total params: 23,437,898
Trainable params: 23,437,898
Non-trainable params: 0
__________________________________________________________________________________________________
Il est recommandé de le visualiser comme il convient pendant la modélisation réelle, car cela améliorera le débogage.
Je voudrais utiliser Adam pour optimiser la fonction de perte comme une entropie croisée. Regardons la précision des mots pour chaque époque.
Je veux enregistrer le modèle toutes les 5 époques.
L'exemple de mise en œuvre est le suivant
model.compile(optimizer='adam', loss='categorical_crossentropy',
metrics=['accuracy'])
# define save condition
dir_path = 'saved_models/LSTM/'
save_every = 5
train_schedule = [save_every for i in range(divmod(epochs,save_every)[0])]
if divmod(epochs,save_every)[1] != 0:
train_schedule += [divmod(epochs,save_every)[1]]
#run training
total_epochs = 0
for epoch in train_schedule:
history = model.fit([encoder_input_tensor, decoder_input_tensor],
np.apply_along_axis(lambda x: np_utils.to_categorical(x,num_classes=vocab_tar_size), 1, decoder_target_tensor),
batch_size=batch_size,
epochs=epoch,
validation_split=0.2)
total_epochs += epoch
filename = str(total_epochs) + 'epochs_LSTM.h5'
model.save(dir_path+filename)
Je fais diverses choses, mais les seules sont model.compile
et model.fit
. Je pense que seuls ces deux sont suffisants pour le minimum.
Passez la méthode d'optimisation, la fonction de perte et la métrique d'évaluation à model.compile
comme options.
Ensuite, il sera appris et exécuté avec model.fit
.
Les paramètres les plus importants donnés à model.fit
sont les données d'entrée et les données de réponse correctes.
Les données de réponse correctes sont np.apply_along_axis (lambda x: np_utils.to_categorical (x, num_classes = vocal_tar_size), 1, decoder_target_tensor)
C'est parce que je veux convertir chaque élément de decoder_target_tensor
en un format encodé à chaud.
Les bogues peuvent être trouvés rapidement en effectuant des visualisations appropriées pour vérifier la cohérence des dimensions, ou en substituant des valeurs spécifiques le cas échéant. Comme chaque couche peut être traitée comme une fonction, vous pouvez obtenir la sortie de la valeur concrète en substituant la valeur concrète.
La partie prétraitement est la suivante Traduction automatique neuronale avec attention https://www.tensorflow.org/tutorials/text/nmt_with_attention
La base de code pour la partie apprentissage / inférence est la suivante Sequence to sequence example in Keras (character-level). https://keras.io/examples/lstm_seq2seq/
Les données utilisées pour l'apprentissage sont les suivantes https://github.com/odashi/small_parallel_enja
Le référentiel contenant le code de cet article https://github.com/nagiton/simple_NMT