Dies ist ein Memo für mich, während ich Einführung in Anwendungen zur Verarbeitung natürlicher Sprache in 15 Schritten lese. Dieses Mal werde ich in Kapitel 3, Schritt 09 meine eigenen Punkte aufschreiben.
Lassen Sie uns einen Klassifikator für mehrere Klassen mithilfe des im vorherigen Kapitel beschriebenen mehrschichtigen Perzeptrons implementieren.
--softmax: Aktivierungsfunktion zur Mehrklassenidentifikation ⇄ Sigmoid (zur 2-Klassenidentifikation) --categorical_crossentropy: Verlustfunktion für die Identifizierung mehrerer Klassen ⇄ binary_crossentropy (für die Identifizierung 2 Klassen)
Die Anzahl der Einheiten in der Ausgabeebene unterscheidet sich zwischen dem Zwei-Klassen-Klassifikator und dem Mehrklassen-Klassifikator, und die Lehrerbezeichnung wird unterschiedlich angegeben.
0,
-> Class ID is 01,
-> Class ID is 12,
-> Class ID is 2[1, 0, 0],
-> Class ID is 0[0, 1, 0],
-> Class ID is 1[0, 0, 1],
-> Class ID is 2Softmax wird oft verwendet.
Durch Durchlaufen von Softmax wird der Wert mit der Größendifferenz zwischen 0 und 1 eingestellt und nähert sich dann 0 oder 1, so dass das Größenverhältnis größer wird.
Wenn es log2N-Einheiten gibt, ist eine N-Klassen-Klassifizierung theoretisch möglich, indem diese Ausgänge 0 oder 1 kombiniert werden, so dass eine Zwei-Klassen-Klassifizierung mit dem Ausgang 0 oder 1 einer Einheit durchgeführt werden kann. Die untere Einheit muss jedoch in mehr als einer Klasse dieselbe 0 oder 1 lernen, was intuitiv unnatürlich erscheint und das Lernen nicht gut verläuft.
Im Gegensatz zu binary_crossentropy für die Identifizierung in zwei Klassen wird categoryical_crossentropy für die Identifizierung in mehreren Klassen verwendet.
Bei der Klassifizierung in die N-Klasse müssen N Neuronen in der Ausgabeschicht vorbereitet werden. Zu diesem Zeitpunkt muss das Ausgabeetikett angegeben werden, damit N Neuronen anstelle der Klassen-ID selbst den Wert 0 oder 1 zugewiesen werden können.
--Konvertieren Sie mit keras.util.to_categorical in einen One-Hot-Ausdruck
Montagemuster | Punkt |
---|---|
Basic | #Aufbau ・ Stellen Sie die Anzahl der Eingangsabmessungen des Modells separat ein ・ Stellen Sie die Anzahl der Ausgangsabmessungen des Modells separat ein ・ Während des Lernens ・ Lehrer beschriften eins-Müssen in heiße Darstellung konvertieren ・ Zum Zeitpunkt der Identifizierung · Eins-Erfordert die Konvertierung von der Hot-Darstellung in die Klassen-ID #Lauf ・ Während des Lernens ・ Vectorizer passen_Transformation ausführen ・ Passen Sie die Ausführung des Klassifikators an ・ Zum Zeitpunkt der Identifizierung ・vectorizerのTransformation ausführen ・ Vorhersage des Klassifikators ausführen |
Keras Scikit-mit Lern-API sklearn.pipeline.Einbindung in die Pipeline |
#Aufbau ・ Stellen Sie die Anzahl der Eingangsabmessungen des Modells separat ein ・ Stellen Sie die Anzahl der Ausgangsabmessungen des Modells separat ein #Lauf ・ Während des Lernens ・ Passen Sie die Ausführung des Vektorisierers an ・ Pipeline-Fit-Ausführung ・ Zum Zeitpunkt der Identifizierung ・ Ausführung der Pipeline-Vorhersage |
In keras.wrappers.scikit_learn.KerasClassifier führt fit () den Prozess aus, der to_categorical entspricht, und Predict () führt den Prozess aus, der np.argmax entspricht. Durch die Verwendung von Pipeline können fit () und Predict () von Vektorisierer und Klassifizierer zusammen ausgeführt werden. Beachten Sie jedoch, dass nur fit () von Vektorisierer separat erforderlich ist, um die Eingabedimension beim Festlegen des Modells anzugeben.
Ergänzungen / Änderungen gegenüber dem vorherigen Kapitel (Schritt 06)
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')) #1: Aktivierungsfunktion der Ausgabeschicht
mlp.compile(loss='categorical_crossentropy', #2: Verlustfunktion
optimizer='adam')
return mlp
def train(self, texts, labels):
~~
feature_dim = len(vectorizer.get_feature_names())
n_labels = max(labels) + 1
#3: Identifikator
classifier = KerasClassifier(build_fn=self._build_mlp,
input_dim=feature_dim,
hidden_units=32,
output_dim=n_labels)
~~
Ausführungsergebnis
# evaluate_dialogue_agent.Ändern Sie den Namen des py-Lademoduls nach Bedarf
from dialogue_agent_sklearn_pipeline import DialogueAgent
$ docker run -it -v $(pwd):/usr/src/app/ 15step:latest python evaluate_dialogue_agent.py
0.65957446
Normale Implementierung (Schritt 01): 37,2% Vorverarbeitung hinzugefügt (Schritt 02): 43,6% Änderung der Vorverarbeitung + Merkmalsextraktion (Schritt 04): 58,5% Vorverarbeitung + Änderung der Merkmalsextraktion + Änderung des Klassifikators (Schritt 06): 61,7% Vorverarbeitung + Änderung der Merkmalsextraktion + Änderung des Klassifikators (Schritt 09): 66,0%
Hidden_units
und classifier__epochs
wurden zum Argument der Zugmethode der DialogueAgent-Klasse hinzugefügt.
dialogue_agent_sklearn_pipeline.py
def train(self, texts, labels, hidden_units = 32, classifier__epochs = 100):
~~
classifier = KerasClassifier(build_fn=self._build_mlp,
input_dim=feature_dim,
hidden_units=hidden_units,
output_dim=n_labels)
~~
pipeline.fit(texts, labels, classifier__epochs=classifier__epochs)
~~
Geben Sie beim Aufrufen der Zugmethode der DialogueAgent-Klasse hidden_units
und classifier__epochs
an.
evaluate_dialogue_agent.py
HIDDEN_UNITS = 64
CLASSIFIER_EPOCHS = 50
# Training
training_data = pd.read_csv(join(BASE_DIR, './training_data.csv'))
dialogue_agent = DialogueAgent()
dialogue_agent.train(training_data['text'], training_data['label'], HIDDEN_UNITS, CLASSIFIER_EPOCHS)
Ausführungsergebnis
Epoch 50/50
917/917 [==============================] - 0s 288us/step - loss: 0.0229
###Ich habe mir auch verschiedene Dinge angesehen###
# pprint.pprint(dialogue_agent.pipeline.steps)
[('vectorizer',
TfidfVectorizer(analyzer='word', binary=False, decode_error='strict',
dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
lowercase=True, max_df=1.0, max_features=None, min_df=1,
ngram_range=(1, 2), norm='l2', preprocessor=None, smooth_idf=True,
stop_words=None, strip_accents=None, sublinear_tf=False,
token_pattern='(?u)\\b\\w\\w+\\b',
tokenizer=<bound method DialogueAgent._tokenize of <dialogue_agent_sklearn_pipeline.DialogueAgent object at 0x7f7fc81bd128>>,
use_idf=True, vocabulary=None)),
('classifier',
<keras.wrappers.scikit_learn.KerasClassifier object at 0x7f7fa4a6a320>)]
# pprint.pprint(dialogue_agent.pipeline.steps[1][1].get_params())
{'build_fn': <bound method DialogueAgent._build_mlp of <dialogue_agent_sklearn_pipeline.DialogueAgent object at 0x7f7fc81bd128>>,
'hidden_units': 64,
'input_dim': 3219,
'output_dim': 49}
# print([len(v) for v in dialogue_agent.pipeline.steps[1][1].model.layers[0].get_weights()])
[3219, 64]
# print([len(v) for v in dialogue_agent.pipeline.steps[1][1].model.layers[1].get_weights()])
[64, 49]
Es kann bestätigt werden, dass die Dimension der Eingabeebene 3219, die Dimension der verborgenen Ebene 64 und die Dimension der Ausgabeebene 49 beträgt. Es wurde bestätigt, dass es aus dem Format der Gewichtsliste der 0. Schicht und der 1. Schicht korrekt war. (Mit fortschreitendem Lernen wird diese Liste der Gewichte immer mehr aktualisiert.)
Recommended Posts