Ceci est un mémo pour moi pendant que je lis Introduction aux applications de traitement du langage naturel en 15 étapes. Cette fois, au chapitre 3, étape 12, notez vos propres points. J'ai étudié CNN lui-même, donc le contenu est approximatif.
Dans le chapitre précédent, en introduisant les incorporations de mots, il est devenu possible de gérer des expressions distribuées de mots comme des quantités de caractéristiques. Cependant, il est nécessaire de prendre le total ou la moyenne des expressions distribuées afin de l'adapter à la quantité de caractéristiques au niveau de la phrase, ce qui rend la prédiction inférieure au système BoW. Dans ce chapitre, nous allons construire un réseau de neurones convolutifs (CNN) avec une séquence d'expressions distribuées de mots disposées sous une forme correspondant à une phrase en entrée. Notez que le CNN utilisé pour l'analyse d'image familière est bidimensionnel, donc le CNN lorsqu'il s'agit de traitement du langage naturel (classification de texte, etc.) est unidimensionnel.
12.1 ~ 12.4
Couche CNN | Contenu |
---|---|
Convolutional layer | ·contribution -Séquence de représentation distribuée des mots obtenus par embeddings de mots -Lors de l'empilement des couches CNN, la chaîne de sortie de la couche Pooling de la couche précédente ・ Alignez la longueur de la chaîne d'expression distribuée de chaque mot qui compose la phrase ・ Ignorer la longueur excessive ・ Remplissez la pénurie avec zéro vecteur -Kernel pour la direction de la structure de la phrase_Pour chaque taille, multipliez par le poids et ajoutez un biais pour en faire l'une des sorties -Répétez la même opération pour chaque foulée dans le sens de la structure de la phrase, mais utilisez le même poids que le calque précédent:weight sharing |
Pooling layer | ·contribution -Chaîne de sortie de la couche de conversion ・ Il existe un pooling Max et un pooling moyen, mais le pooling Max, qui est un processus non linéaire, a des performances plus élevées. -La même opération peut être répétée pour chaque foulée dans le sens de la structure de la phrase, mais il existe également une méthode de traitement en une seule fois sans régler la foulée;global max pooling, global average pooling |
fully-connected layer (densely-connected layer;Couche entièrement connectée) |
・ Je veux entrer dans le perceptron multicouche pour la classification multi-classe -Comme la sortie de la couche de regroupement est un tableau bidimensionnel, convertissez-le en un tableau unidimensionnel qui peut être entré dans le perceptron multicouche. |
Dans le chapitre précédent, les expressions distribuées ont été totalisées, j'ai donc essayé de les faire la moyenne.
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)
#Le contenu est presque le même que celui de l'étape 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 <Nom du module implémenté> 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))
Dans ce qui précède, le classificateur était SVC, changeons-le donc en NN.
Puisque la représentation distribuée de chaque mot est moyennée, la dimension de représentation distribuée textes.shape [1]
est définie comme input_dim du classificateur Keras.
~~
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)
~~
Étant donné que la représentation distribuée de l'incorporation de mots est un tableau à deux dimensions, entrez-la dans le calque Dense après avoir inséré le calque Aplatir.
#Construction de modèles
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'])
Entrez la représentation distribuée de l'incorporation de mots dans la couche convolutionnelle de CNN, mais définissez kernel_size à la dimension x_train.shape [1]
de la représentation distribuée et faites-en la même configuration que la couche dense.
#Construction de modèles
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'])
Entrez la représentation distribuée de l'incorporation de mots dans la couche convolutionnelle de CNN. Les détails sont omis car c'est comme dans le livre.
Couche d'intégration
Embedding(input_dim=word_num + 1,
output_dim=embedding_dim,
weights=[weights_with_zero],
*args, **kwargs)
↓
# *args, **kwargs ressemble en fait à ceci
Embedding(input_dim=word_num + 1,
output_dim=embedding_dim,
weights=[weights_with_zero],
input_shape=(MAX_SEQUENCE_LENGTH, ),
trainable=False)
--trainable: ne pas mettre à jour les poids pendant l'entraînement (l'intégration en utilisant des poids déjà appris ne nécessite pas de mises à jour de poids par apprentissage) --input_shape: lors de l'ajout d'une couche avec add in Keras, spécifiez-la comme première couche d'entrée --input_dim / output_dim: Dim d'entrée / sortie des poids des couches d'incorporation. La dimension de sortie de la couche Embedding est égale à output_dim
Représentation distribuée des embeddings de mots | Identifiant | Résultat d'exécution |
---|---|---|
total | SVC | 0.40425531914893614 |
moyenne | SVC | 0.425531914893617 |
total/moyenne | NN | 0.5638297872340425 / 0.5531914893617021 |
Restez en ligne | Embedding -> Flatten -> Dense | 0.5319148936170213 |
Restez en ligne | Embedding -> CNN(Dense) | 0.5 |
Restez en ligne | Embedding -> CNN | 0.6808510638297872 |
Recommended Posts