Dies ist ein Memo für mich, während ich Einführung in Anwendungen zur Verarbeitung natürlicher Sprache in 15 Schritten lese. Notieren Sie sich diesmal in Kapitel 3, Schritt 12 Ihre eigenen Punkte. Ich habe CNN selbst studiert, daher ist der Inhalt grob.
Im vorherigen Kapitel wurde es durch die Einführung von Worteinbettungen möglich, verteilte Wortausdrücke als Merkmalsgrößen zu behandeln. Es ist jedoch notwendig, die Summe oder den Durchschnitt der verteilten Ausdrücke zu nehmen, um sie auf die Merkmalsmenge auf Satzebene zuzuschneiden, wodurch die Vorhersage dem BoW-System unterlegen ist. In diesem Kapitel werden wir ein Faltungs-Neuronales Netzwerk (CNN) mit einer Folge verteilter Ausdrücke von Wörtern aufbauen, die in einer Form angeordnet sind, die einem Satz als Eingabe entspricht. Beachten Sie, dass das für die vertraute Bildanalyse verwendete CNN zweidimensional ist, sodass das CNN bei der Verarbeitung natürlicher Sprache (Textklassifizierung usw.) eindimensional ist.
12.1 ~ 12.4
CNN-Schicht | Inhalt |
---|---|
Convolutional layer | ·Eingang -Verteilte Darstellungssequenz von Wörtern, die durch Worteinbettungen erhalten wurden - Beim Stapeln von CNN-Ebenen wird die Ausgabezeichenfolge der Pooling-Ebene der vorherigen Ebene angezeigt ・ Richten Sie die Länge der verteilten Ausdruckszeichenfolge jedes Wortes aus, aus dem der Satz besteht ・ Ignorieren Sie die Überlänge ・ Füllen Sie den Mangel mit dem Vektor Null aus -Kernel für die Richtung der Satzstruktur_Multiplizieren Sie für jede Größe mit dem Gewicht und fügen Sie eine Vorspannung hinzu, um sie zu einer der Ausgaben zu machen - Wiederholen Sie die gleiche Operation für jeden Schritt in Richtung der Satzstruktur, verwenden Sie jedoch das gleiche Gewicht wie in der vorherigen Ebene:weight sharing |
Pooling layer | ·Eingang -Faltungsschicht-Ausgabezeichenfolge ・ Es gibt Max Pooling und Average Pooling, aber Max Pooling, ein nichtlinearer Prozess, weist eine höhere Leistung auf. -Die gleiche Operation kann für jeden Schritt in Richtung der Satzstruktur wiederholt werden, es gibt jedoch auch eine Methode zur Verarbeitung auf einmal, ohne den Schritt einzustellen.global max pooling, global average pooling |
fully-connected layer (densely-connected layer;Vollständig verbundene Schicht) |
・ Ich möchte eine Eingabe in das mehrschichtige Perzeptron zur Klassifizierung mehrerer Klassen vornehmen - Da die Ausgabe der Pooling-Schicht ein zweidimensionales Array ist, konvertieren Sie sie in ein eindimensionales Array, das in das mehrschichtige Perzeptron eingegeben werden kann. |
Im vorherigen Kapitel wurden die verteilten Ausdrücke summiert, daher habe ich versucht, sie zu mitteln.
import numpy as np
from gensim.models import Word2Vec
from sklearn.svm import SVC
from tokenizer import tokenize
from sklearn.pipeline import Pipeline
class DialogueAgent:
def __init__(self):
self.model = Word2Vec.load(
'./latest-ja-word2vec-gensim-model/word2vec.gensim.model') # <1>
def train(self, texts, labels):
pipeline = Pipeline([
('classifier', SVC()),
])
pipeline.fit(texts, labels)
self.pipeline = pipeline
def predict(self, texts):
return self.pipeline.predict(texts)
#Der Inhalt entspricht fast dem von Schritt 11
def calc_text_feature(self, text):
~~
# return np.sum(word_vectors, axis=0)
return np.average(word_vectors, axis=0)
evaluate_dialogue_agent.py
from os.path import dirname, join, normpath
import pandas as pd
import numpy as np
from sklearn.metrics import accuracy_score
from <Modulname implementiert> import DialogueAgent
if __name__ == '__main__':
BASE_DIR = normpath(dirname(__file__))
# Training
training_data = pd.read_csv(join(BASE_DIR, './training_data.csv'))
dialogue_agent = DialogueAgent()
X_train = np.array([dialogue_agent.calc_text_feature(text) for text in training_data['text']])
y_train = np.array(training_data['label'])
dialogue_agent.train(X_train, y_train)
# Evaluation
test_data = pd.read_csv(join(BASE_DIR, './test_data.csv'))
X_test = np.array([dialogue_agent.calc_text_feature(text) for text in test_data['text']])
y_test = np.array(test_data['label'])
y_pred = dialogue_agent.predict(X_test)
print(accuracy_score(y_test, y_pred))
Oben war der Klassifikator SVC, also ändern wir ihn in NN. Da die verteilte Darstellung jedes Wortes gemittelt wird, wird die verteilte Darstellungsdimension "texts.shape [1]" als input_dim des Keras-Klassifikators festgelegt.
~~
def _build_mlp(self, input_dim, hidden_units, output_dim):
mlp = Sequential()
mlp.add(Dense(units=hidden_units,
input_dim=input_dim,
activation='relu'))
mlp.add(Dense(units=output_dim, activation='softmax'))
mlp.compile(loss='categorical_crossentropy',
optimizer='adam')
return mlp
def train(self, texts, labels, hidden_units = 32, classifier__epochs = 100):
feature_dim = texts.shape[1]
print(feature_dim)
n_labels = max(labels) + 1
classifier = KerasClassifier(build_fn=self._build_mlp,
input_dim=feature_dim,
hidden_units=hidden_units,
output_dim=n_labels)
pipeline = Pipeline([
('classifier', classifier),
])
pipeline.fit(texts, labels, classifier__epochs=classifier__epochs)
self.pipeline = pipeline
def predict(self, texts):
return self.pipeline.predict(texts)
~~
Da die verteilte Darstellung der Worteinbettung ein zweidimensionales Array ist, geben Sie sie nach dem Einfügen der Ebene "Abflachen" in die Ebene "Dicht" ein.
#Modellbau
model = Sequential()
model.add(get_keras_embedding(we_model.wv,
input_shape=(MAX_SEQUENCE_LENGTH, ),
trainable=False))
model.add(Flatten())
model.add(Dense(units=256, activation='relu'))
model.add(Dense(units=128, activation='relu'))
model.add(Dense(units=n_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
Geben Sie die verteilte Darstellung der Worteinbettung in die Faltungsschicht von CNN ein, setzen Sie jedoch kernel_size auf die Dimension "x_train.shape [1]" der verteilten Darstellung und nehmen Sie dieselbe Konfiguration wie die dichte Schicht vor.
#Modellbau
model = Sequential()
model.add(get_keras_embedding(we_model.wv,
input_shape=(MAX_SEQUENCE_LENGTH, ),
trainable=False)) # <6>
# 1D Convolution
model.add(Conv1D(filters=256, kernel_size=x_train.shape[1], strides=1, activation='relu'))
# Global max pooling
model.add(MaxPooling1D(pool_size=int(model.output.shape[1])))
model.add(Flatten())
model.add(Dense(units=128, activation='relu'))
model.add(Dense(units=n_classes, activation='softmax'))
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
Geben Sie die verteilte Darstellung der Worteinbettung in die Faltungsschicht von CNN ein. Details werden weggelassen, da es wie im Buch ist.
Einbettungsschicht
Embedding(input_dim=word_num + 1,
output_dim=embedding_dim,
weights=[weights_with_zero],
*args, **kwargs)
↓
# *args, **kwargs sieht tatsächlich so aus
Embedding(input_dim=word_num + 1,
output_dim=embedding_dim,
weights=[weights_with_zero],
input_shape=(MAX_SEQUENCE_LENGTH, ),
trainable=False)
--trainable: Aktualisieren Sie die Gewichte während des Trainings nicht (Das Einbetten erfolgt mit bereits erlernten Gewichten, sodass Gewichte nicht durch Lernen aktualisiert werden können.) --input_shape: Wenn Sie eine Ebene mit Keras hinzufügen hinzufügen, geben Sie sie als erste Eingabeebene an --input_dim / output_dim: In / Out-Dim der Einbettungsebenengewichte. Die Ausgabedimension der Einbettungsebene entspricht output_dim
Verteilte Darstellung von Worteinbettungen | Identifikator | Ausführungsergebnis |
---|---|---|
gesamt | SVC | 0.40425531914893614 |
durchschnittlich | SVC | 0.425531914893617 |
gesamt/durchschnittlich | NN | 0.5638297872340425 / 0.5531914893617021 |
Bleiben Sie in der Schlange | Embedding -> Flatten -> Dense | 0.5319148936170213 |
Bleiben Sie in der Schlange | Embedding -> CNN(Dense) | 0.5 |
Bleiben Sie in der Schlange | Embedding -> CNN | 0.6808510638297872 |
Recommended Posts