Referenz-URL: https://www.tensorflow.org/tutorials/keras/text_classification?hl=ja
Mach Folgendes
import tensorflow as tf
from tensorflow import keras
import numpy as np
#Tensorflow ver Bestätigung
print(tf.__version__)
2.3.0
Verwenden Sie den IMDB-Datensatz
num_words = 10000
dient zum Speichern von 10.000 am häufigsten vorkommenden Wörtern
Selten erscheinende Wörter werden verworfen, um die Datengröße überschaubar zu machen
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
Die Daten sind als positiv oder negativ gekennzeichnet, wobei eine Reihe von Ganzzahlen die Wörter in der Filmkritik darstellen 0 zeigt negative Bewertungen an, 1 zeigt positive Bewertungen an
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
Filmkritiken variieren in der Länge für jede Daten Die Eingabe in das neuronale Netz muss gleich lang sein und muss aufgelöst werden
len(train_data[0]), len(train_data[1])
(218, 189)
#Ein Wörterbuch, das Wörter Ganzzahlen zuordnet
word_index = imdb.get_word_index()
#Der erste Teil des Index ist reserviert
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"
Es gibt zwei Möglichkeiten, die Dateneingabe in das neuronale Netz zu gestalten.
Konvertieren Sie ein Array in einen Vektor von 0s und 1s, der das Auftreten von Wörtern darstellt, ähnlich wie bei der One-Hot-Codierung
Zum Beispiel ist das Array [3, 5] ein 10.000-dimensionaler Vektor mit allen Nullen außer den Indizes 3 und 5. Und dies ist die erste Schicht des Netzwerks, dh die dichte Schicht, die Gleitkomma-Vektordaten verarbeiten kann. Dies ist jedoch eine speicherintensive Methode, die eine Matrix von Wörtern x Überprüfungen erfordert.
Richten Sie das Array auf die gleiche Länge aus, indem Sie eine Ganzzahl in Form der Anzahl der Samples * maximaler Länge auffüllen und tensorisieren Machen Sie die Einbettungsschicht, die dieses Format verarbeiten kann, zur ersten Schicht des Netzwerks
Letzteres wird in diesem Tutorial übernommen
Verwenden Sie die Funktion pad_sequences
, um die Länge zu standardisieren
Referenz: Sequenzvorverarbeitung - Keras-Dokumentation
--value: Wert für das Pad --Padding: Position zum Pad (vor oder nach) --maxlen: Maximale Länge des Arrays Wenn nicht angegeben, ist dies die maximale Länge in einer bestimmten Sequenz.
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)
#Stellen Sie sicher, dass die Längen gleich sind
len(train_data[0]), len(train_data[1])
(256, 256)
#Überprüfen Sie die ersten aufgefüllten Daten
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
Nimmt ein ganzzahlig codiertes Vokabular und sucht nach dem eingebetteten Vektor, der jedem Wortindex entspricht Eingebettete Vektoren werden während des Modelltrainings gelernt Eine Dimension wird der Ausgabematrix zur Vektorisierung hinzugefügt Folglich sind die Abmessungen (Stapel, Reihenfolge, Einbettung) Einfach ausgedrückt, gibt es eine Vektordarstellung jedes Wortes als Eingabe zurück.
keras.layers.GlobalAveragePooling1D
GlobalAveragePooling1D-Ebene Ermitteln Sie für jede Stichprobe den Mittelwert in der Dimension der Sequenz und geben Sie einen Vektor fester Länge zurück Nehmen Sie einfach den Durchschnittswert für jede Dimension des Wortvektors (Komprimierung der Informationsmenge).
Vollständig verbundene Ebene mit 16 versteckten Einheiten activity = 'relu' gibt die Aktivierungsfunktion ReLU an
Vollständig mit einem Ausgabeknoten verbinden Bei Verwendung von Sigmoid für die Aktivierungsfunktion ist der Ausgabewert ein Gleitkomma zwischen 0 und 1, der die Wahrscheinlichkeit oder Gewissheit darstellt.
#Das Eingabeformat ist die Anzahl der Vokabeln, die in Filmkritiken verwendet werden (10).,000 Wörter)
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
_________________________________________________________________
Das obige Modell hat zwei Zwischen- oder "versteckte" Ebenen zwischen der Eingabe und der Ausgabe. Die Ausgabe (Einheit, Knoten oder Neuron) ist die Anzahl der Dimensionen der internen Darstellung dieser Schicht. Mit anderen Worten, der Freiheitsgrad, den dieses Netzwerk beim Erwerb interner Repräsentationen durch Lernen hat.
Wenn das Modell mehr versteckte Einheiten hat (mehr Dimensionen im internen Darstellungsraum) Wenn mehr Ebenen oder beides vorhanden sind, kann das Netzwerk komplexere interne Darstellungen lernen. Infolgedessen nimmt jedoch der Rechenaufwand für das Netzwerk zu, und Muster, die Sie nicht lernen möchten, werden gelernt. Muster, die Sie nicht lernen möchten, sind Muster, die die Leistung von Trainingsdaten verbessern, nicht jedoch die Leistung von Testdaten. Dieses Problem wird als Überanpassung bezeichnet
Ein Modell für das Lernen definieren
--optimer: Optimierer
model.compile(optimizer='adam',
loss='binary_crossentropy',
metrics=['accuracy'])
Überprüfen Sie beim Training die Genauigkeitsrate mit Daten, die das Modell nicht sieht Erstellen Sie einen Validierungssatz, indem Sie 10.000 Proben von den ursprünglichen Trainingsdaten trennen Die Verifizierungsdaten werden zum Anpassen von Hyperparametern beim Erstellen eines Modells verwendet.
x_val = train_data[:10000]
partial_x_train = train_data[10000:]
y_val = train_labels[:10000]
partial_y_train = train_labels[10000:]
Trainieren Sie ein Modell mit 40 Epochen mit einer Mini-Charge von 512 Proben Infolgedessen werden alle in x_train und y_train enthaltenen Proben 40 Mal wiederholt. Verwenden Sie während des Trainings 10.000 Proben von Validierungsdaten, um den Modellverlust und die Genauigkeit zu überwachen
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
Es werden zwei Werte zurückgegeben
results = model.evaluate(test_data, test_labels, verbose=2)
print(results)
782/782 - 1s - loss: 0.3297 - accuracy: 0.8723
[0.32968297600746155, 0.8723199963569641]
Visualisieren Sie den Lernfortschritt
Durch die Visualisierung des Lernfortschritts kann leichter festgestellt werden, ob Überlernen auftritt.
model.fit ()
gibt ein History-Objekt zurück, das ein Wörterbuch enthält, das alles aufzeichnet, was während des Trainings passiert ist
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() #Löschen Sie die Figur
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()
In der obigen Grafik sind die Punkte der Verlust und die korrekte Antwortrate während des Trainings, und die durchgezogene Linie ist der Verlust und die korrekte Antwortrate während der Überprüfung.
Es ist seit etwa 20 Epochen flach. Dies ist ein Beispiel für Überlernen Die Leistung des Modells ist in den Trainingsdaten hoch, aber nicht so hoch in den Daten, die noch nie gesehen wurden. Über diesen Punkt hinaus ist das Modell überoptimiert und lernt interne Darstellungen, die für Trainingsdaten charakteristisch sind, aber nicht auf Testdaten verallgemeinert werden können.
In diesem Fall kann Überlernen verhindert werden, indem das Training nach 20 Epochen abgebrochen wird. Verwenden Sie Rückruf oder Regularisierung, um Überlernen zu vermeiden (führen Sie dies in einem anderen Lernprogramm durch).
Recommended Posts