2016-06-14 59 views
6

IMDB example kapalı bir BLSTM tabanlı çalışıyorum, ancak sürümler etiketler için sıralı bir sıralama değil, sınıflandırma değil. Basitlik için, bunu bir POS etiketleme modeli olarak kullanabilirsiniz. Girişler kelimelerin cümleleridir, çıktılar etiketlerdir. Örnekte kullanılan sözdizimi, diğer Keras örneklerinin çoğunda sözdiziminde biraz farklıdır, çünkü model.add kullanmaz, ancak bir sıra başlatır. Bu biraz farklı sözdiziminde maskeleme katmanının nasıl ekleneceğini anlayamıyorum.keraslar için maskeleme BLSTM

Modeli çalıştırıp test ettim ve gayet iyi çalışıyor ancak 0'ların doğruluğu tahmin ediliyor ve değerlendiriliyor.

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) 

GÜNCELLEME:

Bu PR birleşti ve gömme tabakasında mask_zero=True ile çalışma var İşte kod. Ama şimdi, modelin korkunç performansını gördükten sonra, çıktıda da maskelemeye ihtiyacım olduğunu farkettim, diğerleri ise model.fit satırında sample_weight kullanmayı önerdi. Bunu 0'ları görmezden gelmek için nasıl yapabilirim?

GÜNCELLEME 2:

yüzden this okuyup 1 ve 0'ların bir matris olarak sample_weight anladım. Çalışıyor olabileceğini düşündüm, ama doğruluk yaklaşık% 50 civarında duruyor ve ben sadece yastıklı parçaları tahmin etmeye çalıştığını fark ettim, ancak onları şimdi 0 olarak tahmin etmeyeceğim, çünkü örneklemeyi kullanmadan önce problem oldu.

Güncel kodu:

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) 
+0

Bu eski bir soru ama bunu çözdünüz mü? Ben aynı aşamadayım ... [doğruluk 'sample_weight' hesaba katılmaz] (https://github.com/fchollet/keras/issues/1642) ve testlerime göre maskeleme yapılmadığını öğrendim (aslında maskelemeyi kullanarak henüz çalışamayacağım farklı bir doğruluk değeri üretir). Doğruluğu olan ikinci bir çıktı oluşturmak için muhtemelen işlevsel API'yi kullanacağım. – jdehesa

+0

Bu soruyu tekrar gözden geçirip, mevcut Keras koduna göre basitleştirmeyi büyük ölçüde takdir edeceksiniz. – Seanny123

cevap

1

bu sorunu çözdü mü? Kodunuzun dolgulu değerler ve kelime indeksleriyle nasıl başa çıktığı çok açık değil. sözcük dizinleri izin hakkında ne 1'den başlayıp https://keras.io/layers/embeddings/ göre

embedded = Embedding(nb_words + 1, output_dim=hidden, 
       input_length=maxlen, mask_zero=True)(sequence) 

yerine

embedded = Embedding(nb_words, output_dim=hidden, 
       input_length=maxlen, mask_zero=True)(sequence) 

belirleyici?