URL de référence: https://www.tensorflow.org/tutorials/keras/text_classification?hl=ja
Faites ce qui suit
--Classez les critiques de films en positives ou négatives à l'aide du texte --Construire un réseau de neurones à classer comme positif ou négatif (classification binaire)
import tensorflow as tf
from tensorflow import keras
import numpy as np
#confirmation de tensorflow ver
print(tf.__version__)
2.3.0
Utiliser le jeu de données IMDB
num_words = 10000
est pour contenir les 10000 mots les plus fréquents
Les mots qui apparaissent rarement sont supprimés pour rendre la taille des données gérable
imdb = keras.datasets.imdb
(train_data, train_labels), (test_data, test_labels) = imdb.load_data(num_words=10000)
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb.npz
17465344/17464789 [==============================] - 0s 0us/step
print("Training entries: {}, labels: {}".format(len(train_data), len(train_labels)))
Training entries: 25000, labels: 25000
Les données sont étiquetées positives ou négatives avec un tableau d'entiers représentant les mots de la critique du film 0 indique des avis négatifs, 1 indique des avis positifs
print(train_data[0])
[1, 14, 22, 16, 43, 530, 973, 1622, 1385, 65, 458, 4468, 66, 3941, 4, 173, 36, 256, 5, 25, 100, 43, 838, 112, 50, 670, 2, 9, 35, 480, 284, 5, 150, 4, 172, 112, 167, 2, 336, 385, 39, 4, 172, 4536, 1111, 17, 546, 38, 13, 447, 4, 192, 50, 16, 6, 147, 2025, 19, 14, 22, 4, 1920, 4613, 469, 4, 22, 71, 87, 12, 16, 43, 530, 38, 76, 15, 13, 1247, 4, 22, 17, 515, 17, 12, 16, 626, 18, 2, 5, 62, 386, 12, 8, 316, 8, 106, 5, 4, 2223, 5244, 16, 480, 66, 3785, 33, 4, 130, 12, 16, 38, 619, 5, 25, 124, 51, 36, 135, 48, 25, 1415, 33, 6, 22, 12, 215, 28, 77, 52, 5, 14, 407, 16, 82, 2, 8, 4, 107, 117, 5952, 15, 256, 4, 2, 7, 3766, 5, 723, 36, 71, 43, 530, 476, 26, 400, 317, 46, 7, 4, 2, 1029, 13, 104, 88, 4, 381, 15, 297, 98, 32, 2071, 56, 26, 141, 6, 194, 7486, 18, 4, 226, 22, 21, 134, 476, 26, 480, 5, 144, 30, 5535, 18, 51, 36, 28, 224, 92, 25, 104, 4, 226, 65, 16, 38, 1334, 88, 12, 16, 283, 5, 16, 4472, 113, 103, 32, 15, 16, 5345, 19, 178, 32]
print(train_labels[0])
1
Les critiques de films varient en longueur pour chaque donnée L'entrée du réseau neuronal doit être de la même longueur et doit être résolue
len(train_data[0]), len(train_data[1])
(218, 189)
#Un dictionnaire qui associe des mots à des entiers
word_index = imdb.get_word_index()
#La première partie de l'index est réservée
word_index = {k:(v+3) for k,v in word_index.items()}
word_index["<PAD>"] = 0
word_index["<START>"] = 1
word_index["<UNK>"] = 2 # unknown
word_index["<UNUSED>"] = 3
reverse_word_index = dict([(value, key) for (key, value) in word_index.items()])
def decode_review(text):
return ' '.join([reverse_word_index.get(i, '?') for i in text])
Downloading data from https://storage.googleapis.com/tensorflow/tf-keras-datasets/imdb_word_index.json
1646592/1641221 [==============================] - 0s 0us/step
decode_review(train_data[0])
"<START> this film was just brilliant casting location scenery story direction everyone's really suited the part they played and you could just imagine being there robert <UNK> is an amazing actor and now the same being director <UNK> father came from the same scottish island as myself so i loved the fact there was a real connection with this film the witty remarks throughout the film were great it was just brilliant so much that i bought the film as soon as it was released for <UNK> and would recommend it to everyone to watch and the fly fishing was amazing really cried at the end it was so sad and you know what they say if you cry at a film it must have been good and this definitely was also <UNK> to the two little boy's that played the <UNK> of norman and paul they were just brilliant children are often left out of the <UNK> list i think because the stars that play them all grown up are such a big profile for the whole film but these children are amazing and should be praised for what they have done don't you think the whole story was so lovely because it was true and was someone's life after all that was shared with us all"
Il existe deux façons principales de façonner l'entrée de données dans le réseau neuronal.
--Convertir un tableau en un vecteur de 0 et de 1 représentant l'occurrence de mots, similaire au codage à chaud --Par exemple, le tableau [3, 5] est un vecteur de 10 000 dimensions avec tous les zéros sauf les index 3 et 5. Et c'est la première couche du réseau, c'est-à-dire la couche dense qui peut gérer des données vectorielles en virgule flottante. Cependant, il s'agit d'une méthode gourmande en mémoire qui nécessite une matrice de mots x critiques.
--Alignez le tableau à la même longueur en remplissant et tenseur un entier sous la forme du nombre d'échantillons * longueur maximale Et faites de la couche Embedding qui peut gérer ce format la première couche du réseau
Ce dernier est adopté dans ce tutoriel
Utilisez la fonction pad_sequences
pour standardiser la longueur
Référence: Prétraitement de la séquence - Documentation Keras
--value: Valeur à remplir --Rembourrage: Position au rembourrage (avant ou après) --maxlen: Longueur maximale du tableau Si non spécifié, ce sera la longueur maximale dans une séquence donnée.
train_data = keras.preprocessing.sequence.pad_sequences(train_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)
test_data = keras.preprocessing.sequence.pad_sequences(test_data,
value=word_index["<PAD>"],
padding='post',
maxlen=256)
#Assurez-vous que les longueurs sont les mêmes
len(train_data[0]), len(train_data[1])
(256, 256)
#Vérifiez les premières données complétées
print(train_data[0])
[ 1 14 22 16 43 530 973 1622 1385 65 458 4468 66 3941
4 173 36 256 5 25 100 43 838 112 50 670 2 9
35 480 284 5 150 4 172 112 167 2 336 385 39 4
172 4536 1111 17 546 38 13 447 4 192 50 16 6 147
2025 19 14 22 4 1920 4613 469 4 22 71 87 12 16
43 530 38 76 15 13 1247 4 22 17 515 17 12 16
626 18 2 5 62 386 12 8 316 8 106 5 4 2223
5244 16 480 66 3785 33 4 130 12 16 38 619 5 25
124 51 36 135 48 25 1415 33 6 22 12 215 28 77
52 5 14 407 16 82 2 8 4 107 117 5952 15 256
4 2 7 3766 5 723 36 71 43 530 476 26 400 317
46 7 4 2 1029 13 104 88 4 381 15 297 98 32
2071 56 26 141 6 194 7486 18 4 226 22 21 134 476
26 480 5 144 30 5535 18 51 36 28 224 92 25 104
4 226 65 16 38 1334 88 12 16 283 5 16 4472 113
103 32 15 16 5345 19 178 32 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0]
keras.layers.Embedding
Prend un vocabulaire codé en entier et recherche un vecteur intégré correspondant à chaque index de mot Les vecteurs intégrés sont appris pendant la formation du modèle Une dimension est ajoutée à la matrice de sortie pour la vectorisation En conséquence, les dimensions sont (lot, séquence, encastrement) En termes simples, il renvoie une représentation vectorielle de chaque mot en entrée.
keras.layers.GlobalAveragePooling1D
Couche GlobalAveragePooling1D Pour chaque échantillon, trouvez la moyenne dans la dimension de la séquence et retournez un vecteur de longueur fixe En termes simples, prenez la valeur moyenne pour chaque dimension du vecteur de mot (compression de la quantité d'informations)
Couche entièrement connectée avec 16 unités cachées activation = 'relu' spécifie la fonction d'activation ReLU
Joindre entièrement à un nœud de sortie En utilisant sigmoïde pour la fonction d'activation, la valeur de sortie sera une virgule flottante entre 0 et 1 représentant la probabilité ou la certitude.
#Le format d'entrée est le nombre de vocabulaire utilisé dans les critiques de films (10),000 mots)
vocab_size = 10000
model = keras.Sequential()
model.add(keras.layers.Embedding(vocab_size, 16))
model.add(keras.layers.GlobalAveragePooling1D())
model.add(keras.layers.Dense(16, activation='relu'))
model.add(keras.layers.Dense(1, activation='sigmoid'))
model.summary()
Model: "sequential"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
embedding (Embedding) (None, None, 16) 160000
_________________________________________________________________
global_average_pooling1d (Gl (None, 16) 0
_________________________________________________________________
dense (Dense) (None, 16) 272
_________________________________________________________________
dense_1 (Dense) (None, 1) 17
=================================================================
Total params: 160,289
Trainable params: 160,289
Non-trainable params: 0
_________________________________________________________________
Le modèle ci-dessus a deux couches intermédiaires ou "cachées" entre l'entrée et la sortie. La sortie (unité, nœud ou neurone) est le nombre de dimensions de la représentation interne de cette couche. En d'autres termes, le degré de liberté dont dispose ce réseau pour acquérir des représentations internes par l'apprentissage.
Si le modèle a plus d'unités cachées (plus de dimensions dans l'espace de représentation interne) Ou, s'il y a plus de couches, ou les deux, le réseau peut apprendre des représentations internes plus complexes. Cependant, en conséquence, la quantité de calcul du réseau augmentera et vous apprendrez des modèles que vous ne souhaitez pas apprendre. Les modèles que vous ne souhaitez pas apprendre sont des modèles qui améliorent les performances des données d'entraînement, mais pas les performances des données de test. Ce problème s'appelle le surajustement.
Définir un modèle d'apprentissage
--optimer: optimiseur
--Cette fois, spécifiez ʻAdam --Autres algorithmes d'optimisation: https://www.tensorflow.org/api_docs/python/tf/keras/optimizers --loss: fonction de perte --Cette fois, spécifiez
entropie croisée binaire --metrics: éléments quantifiés pendant la formation et les tests --Cette fois, spécifiez ʻaccuracy
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
Lors de l'entraînement, vérifiez le taux de précision avec des données que le modèle ne voit pas Créez un jeu de validation en séparant 10000 échantillons des données d'entraînement d'origine Les données de vérification sont utilisées pour ajuster les hyper paramètres lors de la création d'un modèle.
x_val = train_data[:10000]
partial_x_train = train_data[10000:]
y_val = train_labels[:10000]
partial_y_train = train_labels[10000:]
Entraînez un modèle de 40 époques à l'aide d'un mini-lot de 512 échantillons En conséquence, tous les échantillons contenus dans x_train et y_train seront répétés 40 fois. Pendant la formation, utilisez 10000 échantillons de données de validation pour surveiller la perte et la précision du modèle
history = model.fit(partial_x_train,
partial_y_train,
epochs=40,
batch_size=512,
validation_data=(x_val, y_val),
verbose=1)
Epoch 1/40
30/30 [==============================] - 1s 21ms/step - loss: 0.6916 - accuracy: 0.5446 - val_loss: 0.6894 - val_accuracy: 0.6478
Epoch 2/40
30/30 [==============================] - 0s 16ms/step - loss: 0.6855 - accuracy: 0.7160 - val_loss: 0.6815 - val_accuracy: 0.6852
Epoch 3/40
30/30 [==============================] - 1s 17ms/step - loss: 0.6726 - accuracy: 0.7333 - val_loss: 0.6651 - val_accuracy: 0.7548
Epoch 4/40
30/30 [==============================] - 1s 17ms/step - loss: 0.6499 - accuracy: 0.7683 - val_loss: 0.6393 - val_accuracy: 0.7636
Epoch 5/40
30/30 [==============================] - 1s 17ms/step - loss: 0.6166 - accuracy: 0.7867 - val_loss: 0.6045 - val_accuracy: 0.7791
Epoch 6/40
30/30 [==============================] - 1s 17ms/step - loss: 0.5747 - accuracy: 0.8083 - val_loss: 0.5650 - val_accuracy: 0.7975
Epoch 7/40
30/30 [==============================] - 0s 16ms/step - loss: 0.5286 - accuracy: 0.8265 - val_loss: 0.5212 - val_accuracy: 0.8165
Epoch 8/40
30/30 [==============================] - 0s 16ms/step - loss: 0.4819 - accuracy: 0.8442 - val_loss: 0.4807 - val_accuracy: 0.8285
Epoch 9/40
30/30 [==============================] - 1s 17ms/step - loss: 0.4382 - accuracy: 0.8589 - val_loss: 0.4438 - val_accuracy: 0.8415
Epoch 10/40
30/30 [==============================] - 0s 16ms/step - loss: 0.3996 - accuracy: 0.8721 - val_loss: 0.4133 - val_accuracy: 0.8496
Epoch 11/40
30/30 [==============================] - 1s 17ms/step - loss: 0.3673 - accuracy: 0.8774 - val_loss: 0.3887 - val_accuracy: 0.8570
Epoch 12/40
30/30 [==============================] - 0s 16ms/step - loss: 0.3398 - accuracy: 0.8895 - val_loss: 0.3682 - val_accuracy: 0.8625
Epoch 13/40
30/30 [==============================] - 0s 16ms/step - loss: 0.3159 - accuracy: 0.8935 - val_loss: 0.3524 - val_accuracy: 0.8652
Epoch 14/40
30/30 [==============================] - 0s 16ms/step - loss: 0.2961 - accuracy: 0.8995 - val_loss: 0.3388 - val_accuracy: 0.8710
Epoch 15/40
30/30 [==============================] - 0s 16ms/step - loss: 0.2785 - accuracy: 0.9049 - val_loss: 0.3282 - val_accuracy: 0.8741
Epoch 16/40
30/30 [==============================] - 0s 16ms/step - loss: 0.2631 - accuracy: 0.9095 - val_loss: 0.3192 - val_accuracy: 0.8768
Epoch 17/40
30/30 [==============================] - 1s 17ms/step - loss: 0.2500 - accuracy: 0.9136 - val_loss: 0.3129 - val_accuracy: 0.8769
Epoch 18/40
30/30 [==============================] - 0s 16ms/step - loss: 0.2371 - accuracy: 0.9185 - val_loss: 0.3064 - val_accuracy: 0.8809
Epoch 19/40
30/30 [==============================] - 0s 16ms/step - loss: 0.2255 - accuracy: 0.9233 - val_loss: 0.3010 - val_accuracy: 0.8815
Epoch 20/40
30/30 [==============================] - 1s 17ms/step - loss: 0.2155 - accuracy: 0.9265 - val_loss: 0.2976 - val_accuracy: 0.8829
Epoch 21/40
30/30 [==============================] - 1s 17ms/step - loss: 0.2060 - accuracy: 0.9290 - val_loss: 0.2942 - val_accuracy: 0.8823
Epoch 22/40
30/30 [==============================] - 0s 17ms/step - loss: 0.1962 - accuracy: 0.9331 - val_loss: 0.2914 - val_accuracy: 0.8844
Epoch 23/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1877 - accuracy: 0.9374 - val_loss: 0.2894 - val_accuracy: 0.8838
Epoch 24/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1794 - accuracy: 0.9421 - val_loss: 0.2877 - val_accuracy: 0.8850
Epoch 25/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1724 - accuracy: 0.9442 - val_loss: 0.2867 - val_accuracy: 0.8854
Epoch 26/40
30/30 [==============================] - 0s 16ms/step - loss: 0.1653 - accuracy: 0.9479 - val_loss: 0.2862 - val_accuracy: 0.8854
Epoch 27/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1583 - accuracy: 0.9515 - val_loss: 0.2866 - val_accuracy: 0.8842
Epoch 28/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1520 - accuracy: 0.9536 - val_loss: 0.2867 - val_accuracy: 0.8859
Epoch 29/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1459 - accuracy: 0.9563 - val_loss: 0.2868 - val_accuracy: 0.8861
Epoch 30/40
30/30 [==============================] - 0s 16ms/step - loss: 0.1402 - accuracy: 0.9582 - val_loss: 0.2882 - val_accuracy: 0.8860
Epoch 31/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1347 - accuracy: 0.9597 - val_loss: 0.2887 - val_accuracy: 0.8863
Epoch 32/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1295 - accuracy: 0.9625 - val_loss: 0.2899 - val_accuracy: 0.8862
Epoch 33/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1249 - accuracy: 0.9634 - val_loss: 0.2919 - val_accuracy: 0.8856
Epoch 34/40
30/30 [==============================] - 1s 18ms/step - loss: 0.1198 - accuracy: 0.9657 - val_loss: 0.2939 - val_accuracy: 0.8858
Epoch 35/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1155 - accuracy: 0.9677 - val_loss: 0.2957 - val_accuracy: 0.8850
Epoch 36/40
30/30 [==============================] - 1s 18ms/step - loss: 0.1109 - accuracy: 0.9691 - val_loss: 0.2988 - val_accuracy: 0.8850
Epoch 37/40
30/30 [==============================] - 1s 17ms/step - loss: 0.1068 - accuracy: 0.9709 - val_loss: 0.3005 - val_accuracy: 0.8837
Epoch 38/40
30/30 [==============================] - 1s 19ms/step - loss: 0.1030 - accuracy: 0.9718 - val_loss: 0.3045 - val_accuracy: 0.8829
Epoch 39/40
30/30 [==============================] - 0s 17ms/step - loss: 0.0997 - accuracy: 0.9733 - val_loss: 0.3077 - val_accuracy: 0.8816
Epoch 40/40
30/30 [==============================] - 1s 17ms/step - loss: 0.0952 - accuracy: 0.9751 - val_loss: 0.3088 - val_accuracy: 0.8828
Deux valeurs sont renvoyées
results = model.evaluate(test_data, test_labels, verbose=2)
print(results)
782/782 - 1s - loss: 0.3297 - accuracy: 0.8723
[0.32968297600746155, 0.8723199963569641]
Visualisez la progression de l'apprentissage
La visualisation de la progression de l'apprentissage permet de savoir plus facilement s'il y a surapprentissage.
model.fit ()
retourne un objet History contenant un dictionnaire qui enregistre tout ce qui s'est passé pendant l'entraînement
history_dict = history.history
history_dict.keys()
dict_keys(['loss', 'accuracy', 'val_loss', 'val_accuracy'])
import matplotlib.pyplot as plt
acc = history_dict['accuracy']
val_acc = history_dict['val_accuracy']
loss = history_dict['loss']
val_loss = history_dict['val_loss']
epochs = range(1, len(acc) + 1)
# "bo" is for "blue dot"
plt.plot(epochs, loss, 'bo', label='Training loss')
# b is for "solid blue line"
plt.plot(epochs, val_loss, 'b', label='Validation loss')
plt.title('Training and validation loss')
plt.xlabel('Epochs')
plt.ylabel('Loss')
plt.legend()
plt.show()
plt.clf() #Effacer la figure
plt.plot(epochs, acc, 'bo', label='Training acc')
plt.plot(epochs, val_acc, 'b', label='Validation acc')
plt.title('Training and validation accuracy')
plt.xlabel('Epochs')
plt.ylabel('Accuracy')
plt.legend()
plt.show()
Dans le graphique ci-dessus, les points sont la perte et le taux de réponse correcte pendant la formation, et la ligne continue est le taux de perte et de réponse correcte pendant la vérification.
Il est plat depuis une vingtaine d'époques. Ceci est un exemple de surapprentissage Les performances du modèle sont élevées dans les données d'entraînement, mais pas si élevées dans les données qui n'ont jamais été vues. Au-delà de ce point, le modèle est sur-optimisé et apprend des représentations internes qui sont caractéristiques des données d'apprentissage mais ne peuvent pas être généralisées aux données de test.
Dans ce cas, le surapprentissage peut être évité en arrêtant la formation après 20 époques. Pour éviter le surapprentissage, utilisez le rappel ou régularisez (faites-le dans un autre tutoriel)
Recommended Posts