Sto eseguendo un BLSTM basato su IMDB example, ma la mia versione non è una classificazione, piuttosto una previsione di sequenza per le etichette. Per semplicità, puoi trattarlo come un modello di codifica POS. Gli input sono frasi di parole, gli output sono tag. La sintassi utilizzata nell'esempio differisce leggermente nella sintassi dalla maggior parte degli altri esempi di Keras in quanto non utilizza model.add
ma avvia una sequenza. Non riesco a capire come aggiungere un livello di mascheramento in questa sintassi leggermente diversa.mascheramento per keras BLSTM
Ho eseguito il modello e l'ho testato, e funziona benissimo ma è la previsione e la valutazione della precisione degli 0, che sono il mio padding. Ecco il codice:
from __future__ import print_function
import numpy as np
from keras.preprocessing import sequence
from keras.models import Model
from keras.layers.core import Masking
from keras.layers import TimeDistributed, Dense
from keras.layers import Dropout, Embedding, LSTM, Input, merge
from prep_nn import prep_scan
from keras.utils import np_utils, generic_utils
np.random.seed(1337) # for reproducibility
nb_words = 20000 # max. size of vocab
nb_classes = 10 # number of labels
hidden = 500 # 500 gives best results so far
batch_size = 10 # create and update net after 10 lines
val_split = .1
epochs = 15
# input for X is multi-dimensional numpy array with IDs,
# one line per array. input y is multi-dimensional numpy array with
# binary arrays for each value of each label.
# maxlen is length of longest line
print('Loading data...')
(X_train, y_train), (X_test, y_test) = prep_scan(
nb_words=nb_words, test_len=75)
print(len(X_train), 'train sequences')
print(int(len(X_train)*val_split), 'validation sequences')
print(len(X_test), 'heldout sequences')
# this is the placeholder tensor for the input sequences
sequence = Input(shape=(maxlen,), dtype='int32')
# this embedding layer will transform the sequences of integers
# into vectors
embedded = Embedding(nb_words, output_dim=hidden,
input_length=maxlen)(sequence)
# apply forwards LSTM
forwards = LSTM(output_dim=hidden, return_sequences=True)(embedded)
# apply backwards LSTM
backwards = LSTM(output_dim=hidden, return_sequences=True,
go_backwards=True)(embedded)
# concatenate the outputs of the 2 LSTMs
merged = merge([forwards, backwards], mode='concat', concat_axis=-1)
after_dp = Dropout(0.15)(merged)
# TimeDistributed for sequence
# change activation to sigmoid?
output = TimeDistributed(
Dense(output_dim=nb_classes,
activation='softmax'))(after_dp)
model = Model(input=sequence, output=output)
# try using different optimizers and different optimizer configs
# loss=binary_crossentropy, optimizer=rmsprop
model.compile(loss='categorical_crossentropy',
metrics=['accuracy'], optimizer='adam')
print('Train...')
model.fit(X_train, y_train,
batch_size=batch_size,
nb_epoch=epochs,
shuffle=True,
validation_split=val_split)
UPDATE:
ho fuse questo PR e ottenuto che funziona con mask_zero=True
nello strato di incorporamento. Ma ora mi sto rendendo conto dopo aver visto prestazioni terribili del modello che avrei anche dovuto mascherare nell'output, altri hanno suggerito di utilizzare sample_weight invece nella riga model.fit
. Come posso fare questo per ignorare gli 0?
UPDATE 2:
così ho letto this e capito il sample_weight
come una matrice di 1 e 0. Ho pensato che potesse funzionare, ma la mia accuratezza si blocca attorno a% 50, e ho appena scoperto che sta cercando di prevedere le parti imbottite, ma non le prediremo come 0 ora, come era il problema prima di usare sample_weight.
codice attuale:
from __future__ import print_function
import numpy as np
from keras.preprocessing import sequence
from keras.models import Model
from keras.layers.core import Masking
from keras.layers import TimeDistributed, Dense
from keras.layers import Dropout, Embedding, LSTM, Input, merge
from prep_nn import prep_scan
from keras.utils import np_utils, generic_utils
import itertools
from itertools import chain
from sklearn.preprocessing import LabelBinarizer
import sklearn
import pandas as pd
np.random.seed(1337) # for reproducibility
nb_words = 20000 # max. size of vocab
nb_classes = 10 # number of labels
hidden = 500 # 500 gives best results so far
batch_size = 10 # create and update net after 10 lines
val_split = .1
epochs = 10
# input for X is multi-dimensional numpy array with syll IDs,
# one line per array. input y is multi-dimensional numpy array with
# binary arrays for each value of each label.
# maxlen is length of longest line
print('Loading data...')
(X_train, y_train), (X_test, y_test), maxlen, sylls_ids, tags_ids, weights = prep_scan(nb_words=nb_words, test_len=75)
print(len(X_train), 'train sequences')
print(int(len(X_train) * val_split), 'validation sequences')
print(len(X_test), 'heldout sequences')
# this is the placeholder tensor for the input sequences
sequence = Input(shape=(maxlen,), dtype='int32')
# this embedding layer will transform the sequences of integers
# into vectors of size 256
embedded = Embedding(nb_words, output_dim=hidden,
input_length=maxlen, mask_zero=True)(sequence)
# apply forwards LSTM
forwards = LSTM(output_dim=hidden, return_sequences=True)(embedded)
# apply backwards LSTM
backwards = LSTM(output_dim=hidden, return_sequences=True,
go_backwards=True)(embedded)
# concatenate the outputs of the 2 LSTMs
merged = merge([forwards, backwards], mode='concat', concat_axis=-1)
# after_dp = Dropout(0.)(merged)
# TimeDistributed for sequence
# change activation to sigmoid?
output = TimeDistributed(
Dense(output_dim=nb_classes,
activation='softmax'))(merged)
model = Model(input=sequence, output=output)
# try using different optimizers and different optimizer configs
# loss=binary_crossentropy, optimizer=rmsprop
model.compile(loss='categorical_crossentropy',
metrics=['accuracy'], optimizer='adam',
sample_weight_mode='temporal')
print('Train...')
model.fit(X_train, y_train,
batch_size=batch_size,
nb_epoch=epochs,
shuffle=True,
validation_split=val_split,
sample_weight=weights)
È una vecchia domanda ma l'hai risolto? Sono all'incirca allo stesso stadio ... Ho scoperto che [l'accuratezza non tiene conto di sample_weight] (https://github.com/fchollet/keras/issues/1642) e secondo i miei test né il mascheramento (in realtà l'uso del mascheramento produce un valore di precisione diverso che non riuscivo ancora a elaborare). Probabilmente finirò usando l'API funzionale per costruire un secondo risultato con la precisione. – jdehesa
Rivedere questa domanda e semplificarla in relazione all'attuale codice Keras sarebbe molto apprezzata. – Seanny123