Verhindern, über-Einbau von text-Klassifikation mit Word einbetten mit LSTM
Ziel :
- Identifizierung Klasse label mit Benutzer eingegebene Frage (wie Frage
Antwort system). - Daten extrahiert, die von Großen PDF-Datei, und brauchen, um vorherzusagen,
Seitenzahl basierend auf Benutzereingaben. - Hauptsächlich verwendet in der policy-Dokument, wo
Benutzer haben Fragen über Politik und zeigen müssen bestimmte Seite
Anzahl.
Bisherige Umsetzung :
Applied elastic-search, aber sehr geringer Genauigkeit, da die Benutzer geben Sie einen text ein wie "ich muss" == "wollen"
Dataset-Informationen :
Dataset enthält jede Zeile als Text( oder Absatz) und Label (Seitenzahlen). hier dataset klein ist, habe ich nur 500 Zeilen.
Aktuelle Implementierung :
- Angewendet word-einbetten(Handschuh) mit LSTM in Keras-und back-end ist
Tensor-flow - Angewendet Droupout
- Angewendet ActivityRegularization
- Angewendet L2 W_regularizer( von 0,1 bis 0,001)
- Auf verschiedene nb_epoch von 10-600
- Geändert EMBEDDING_DIM von 100-300-Handschuh-Daten
Angewandte NLP für,
- In Kleinschreibung konvertieren
- Entfernen Stop Wort Englisch
- Wortstamm
- Entfernen Nummern
- Entfernen, die URL und die IP-Adresse
Ergebnis : die Genauigkeit der Testdaten(oder Validierung von Daten) ist mit 23% aber auf Zug Daten 91%
Code :
import time
from time import strftime
import numpy as np
from keras.callbacks import CSVLogger, ModelCheckpoint
from keras.layers import Dense, Input, LSTM, ActivityRegularization
from keras.layers import Embedding, Dropout,Bidirectional
from keras.models import Model
from keras.preprocessing.sequence import pad_sequences
from keras.preprocessing.text import Tokenizer
from keras.regularizers import l2
from keras.utils import to_categorical
import pickle
from DataGenerator import *
BASE_DIR = ''
GLOVE_DIR = 'D:/Dataset/glove.6B' # BASE_DIR + '/glove.6B/'
MAX_SEQUENCE_LENGTH = 50
MAX_NB_WORDS = 20000
EMBEDDING_DIM = 300
VALIDATION_SPLIT = 0.2
# first, build index mapping words in the embeddings set
# to their embedding vector
np.random.seed(1337) # for reproducibility
print('Indexing word vectors.')
t_start = time.time()
embeddings_index = {}
if os.path.exists('pickle/glove.pickle'):
print('Pickle found..')
with open('pickle/glove.pickle', 'rb') as handle:
embeddings_index = pickle.load(handle)
else:
print('Pickle not found...')
f = open(os.path.join(GLOVE_DIR, 'glove.6B.300d.txt'), encoding='utf8')
for line in f:
values = line.split()
word = values[0]
coefs = np.asarray(values[1:], dtype='float32')
embeddings_index[word] = coefs
f.close()
with open('pickle/glove.pickle', 'wb') as handle:
pickle.dump(embeddings_index, handle, protocol=pickle.HIGHEST_PROTOCOL)
print('Found %s word vectors.' % len(embeddings_index))
# second, prepare text samples and their labels
print('Processing text dataset')
texts = [] # list of text samples
labels = [] # list of label ids
labels_index = {} # dictionary mapping label name to numeric id
(texts, labels, labels_index) = get_data('D:/PolicyDocument/')
print('Found %s texts.' % len(texts))
# finally, vectorize the text samples into a 2D integer tensor
tokenizer = Tokenizer(nb_words=MAX_NB_WORDS)
tokenizer.fit_on_texts(texts)
sequences = tokenizer.texts_to_sequences(texts)
word_index = tokenizer.word_index
print('Found %s unique tokens.' % len(word_index))
data = pad_sequences(sequences, maxlen=MAX_SEQUENCE_LENGTH)
labels = to_categorical(np.asarray(labels))
print('Shape of data tensor:', data.shape)
print('Shape of label tensor:', labels.shape)
# split the data into a training set and a validation set
indices = np.arange(data.shape[0])
np.random.shuffle(indices)
data = data[indices]
labels = labels[indices]
num_validation_samples = int(VALIDATION_SPLIT * data.shape[0])
x_train = data[:-num_validation_samples]
y_train = labels[:-num_validation_samples]
x_val = data[-num_validation_samples:]
y_val = labels[-num_validation_samples:]
# prepare embedding matrix
num_words = min(MAX_NB_WORDS, len(word_index))
embedding_matrix = np.zeros((num_words + 1, EMBEDDING_DIM))
print('Preparing embedding matrix. :', embedding_matrix.shape)
for word, i in word_index.items():
embedding_vector = embeddings_index.get(word)
if embedding_vector is not None:
# words not found in embedding index will be all-zeros.
embedding_matrix[i] = embedding_vector
# load pre-trained word embeddings into an Embedding layer
# note that we set trainable = False so as to keep the embeddings fixed
embedding_layer = Embedding(embedding_matrix.shape[0],
embedding_matrix.shape[1],
weights=[embedding_matrix],
input_length=MAX_SEQUENCE_LENGTH,
mask_zero=True,
trainable=False)
print('Training model.')
csv_file = "logs/training_log_" + strftime("%Y-%m-%d %H-%M", time.localtime()) + ".csv"
model_file = "models/Model_" + strftime("%Y-%m-%d %H-%M", time.localtime()) + ".mdl"
print("Model file:" + model_file)
csv_logger = CSVLogger(csv_file)
# train a 1D convnet with global maxpooling
sequence_input = Input(shape=(MAX_SEQUENCE_LENGTH,), dtype='int32')
embedded_sequences = embedding_layer(sequence_input)
rate_drop_lstm = 0.15 + np.random.rand() * 0.25
num_lstm = np.random.randint(175, 275)
rate_drop_dense = 0.15 + np.random.rand() * 0.25
x = LSTM(num_lstm, return_sequences=True, W_regularizer=l2(0.001))(embedded_sequences)
x = Dropout(0.5)(x)
x = LSTM(64)(x)
x = Dropout(0.25)(x)
x = ActivityRegularization(l1=0.01, l2=0.001)(x)
preds = Dense(len(labels_index), activation='softmax')(x)
model = Model(sequence_input, preds)
model.compile(loss='categorical_crossentropy',
optimizer='adam',
metrics=['acc'])
model_checkpoint = ModelCheckpoint(model_file, monitor='val_loss', verbose=0, save_best_only=True,
save_weights_only=False, mode='auto')
model.fit(x_train, y_train,
batch_size=1,
nb_epoch=600,
validation_data=(x_val, y_val), callbacks=[csv_logger, model_checkpoint])
score = model.evaluate(x_val, y_val, verbose=0)
print('Test score:', score[0])
print('Test accuracy:', score[1])
t_end = time.time()
total = t_end - t_start
ret_str = "Time needed(s): " + str(total)
print(ret_str)
- und die Frage ist... wie um zu verhindern, dass überanpassung? Dies ist nicht wirklich eine Frage der Programmierung...
- Haben Sie jemals einen genaueren Blick auf den Inhalt Ihrer Prüfung und/oder Validierung festgelegt?
- Sie tun sehr häufigen updates durch die übergabe batch_size=1. Versuchen Sie es, um Werte wie 32, 64, etc. Zu häufige Aktualisierungen können brechen Sie Ihr Netzwerk
- Bitte zeigen deutlich die Frage.
- Schöne Punkte @Nain, ich habe auch batch_size von 1 bis 64
- Hi @onurgüngör, ich habe alle Sachen hier, die ich umgesetzt habe. Alle spezifischen Punkte, die Sie wollen, brauchen, sorgen Sie bitte hier.
InformationsquelleAutor Somnath Kadam | 2017-05-08
Schreibe einen Kommentar Antworten abbrechen
Du musst angemeldet sein, um einen Kommentar abzugeben.
Dropout und BN sind sehr effektiv mit feedforward-NNs. Sie können jedoch zu Problemen mit RNNs (Es gibt viele Veröffentlichungen zu diesem Thema)
Der beste Weg, um Ihre RNN-Modell verallgemeinern besser ist die Erhöhung der dataset-Größe. In deinem Fall (LSTM mit über 200 Zellen), werden Sie wahrscheinlich wollen, um in der Größenordnung von 100.000 oder mehr beschriftet Proben zu trainieren.
Außerdem reduziert man einfach die Parameter wie die Einbettung der Größe und der Menge der Einheiten, die in einigen Ebenen gibt es auch die Möglichkeit der Anpassung der wiederkehrenden Aussetzer in LSTMs.
LSTMs scheinen overfit ganz einfach (so habe ich gelesen).
Dann können Sie sehen, in Keras Dokumentation die Verwendung von
dropout
undrecurrent_dropout
als Parameter jederLSTM
Schicht.Beispiel mit willkürlichen zahlen:
Andere Ursachen können falsche oder Unzureichende Daten:
Haben Sie versucht, das mischen der test und die Validierung von Daten zusammen und erstellen neue Zug-und Validierungsdaten?
Wie viele Sätze haben Sie in den Trainingsdaten? Sind Sie versuchen, mit kleinen Mengen? Verwenden Sie das ganze set oder versuchen dada augmentation (anlegen neuer Sätze und Ihre Klassifizierung - das kann aber sehr schwierig, mit text).
Was Sie beschreiben, klingt wie eine Menge von overfitting.
Ohne weitere Informationen bezüglich der Daten, die den besten Vorschlag für Sie, um zu versuchen, stärker regularisierungsverfahren.
@Daniel schon vorgeschlagen, dass Sie die dropout-Parameter, die Sie nicht verwendet haben -
dropout
undrecurrent_dropout
.Sie können auch versuchen, erhöhen Sie das Verhältnis für die dropout-Schichten, mit stärkeren Regularisierung mit der
W_regularizer
parameter.Könnten andere Optionen eröffnet werden, mit mehr Informationen wie, ob Sie versucht haben Daniel ' s Vorschlag, und was waren die Ergebnisse.
Wettkampf-training Methoden ( als Mittel der Regulation) sein können, lohnt ein Blick in.
Wettkampf-Training-Methoden für die Semi-Supervised Text Klassifikation