2016-05-18 30 views
11

Sinir ağlarına nispeten yeniyim, lütfen cehaletimi bağışlayın. BLSTM örnek here kees adapte çalışıyorum. Örnek metinleri okur ve 0 veya 1 olarak sınıflandırır. POS etiketleme gibi bir şey yapan bir BLSTM istiyorum, ancak lemmatizing veya diğer gelişmiş özellikler gibi ekstralar gerekli değil, sadece temel bir model istiyorum. Verilerim cümlenin bir listesidir ve her bir kelimeye 1-8 kategorisi verilir. Bu verileri, görünmeyen bir cümledeki her kelimenin kategorisini tahmin etmek için kullanabilen bir BLSTM hazırlamak istiyorum.keras Sıralı etiketleme için BLSTM

örn. girdi = ['', 'köpek', 'öyledir', 'kırmızı'] çıktı verir = [2, 4, 3, 7]

Eğer keras örneği en iyi yol değilse, diğer öneriler.

'''Train a Bidirectional LSTM.''' 

from __future__ import print_function 
import numpy as np 
from keras.preprocessing import sequence 
from keras.models import Model 
from keras.layers import Dense, Dropout, Embedding, LSTM, Input, merge 
from prep_nn import prep_scan 


np.random.seed(1337) # for reproducibility 
max_features = 20000 
batch_size = 16 
maxlen = 18 

print('Loading data...') 
(X_train, y_train), (X_test, y_test) = prep_scan(nb_words=max_features, 
               test_split=0.2) 
print(len(X_train), 'train sequences') 
print(len(X_test), 'test sequences') 

print("Pad sequences (samples x time)") 
# type issues here? float/int? 
X_train = sequence.pad_sequences(X_train, value=0.) 
X_test = sequence.pad_sequences(X_test, value=0.) # pad with zeros 

print('X_train shape:', X_train.shape) 
print('X_test shape:', X_test.shape) 

# need to pad y too, because more than 1 ouput value, not classification? 
y_train = sequence.pad_sequences(np.array(y_train), value=0.) 
y_test = sequence.pad_sequences(np.array(y_test), value=0.) 

print('y_train shape:', X_train.shape) 
print('y_test shape:', X_test.shape) 

# 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 128 
embedded = Embedding(max_features, 128, input_length=maxlen)(sequence) 

# apply forwards LSTM 
forwards = LSTM(64)(embedded) 
# apply backwards LSTM 
backwards = LSTM(64, go_backwards=True)(embedded) 

# concatenate the outputs of the 2 LSTMs 
merged = merge([forwards, backwards], mode='concat', concat_axis=-1) 
after_dp = Dropout(0.5)(merged) 
# number after dense has to corresponse to output matrix? 
output = Dense(17, activation='sigmoid')(after_dp) 

model = Model(input=sequence, output=output) 

# try using different optimizers and different optimizer configs 
model.compile('adam', 'categorical_crossentropy', metrics=['accuracy']) 

print('Train...') 
model.fit(X_train, y_train, 
      batch_size=batch_size, 
      nb_epoch=4, 
      validation_data=[X_test, y_test]) 

X_test_new = np.array([[0,0,0,0,0,0,0,0,0,12,3,55,4,34,5,45,3,9],[0,0,0,0,0,0,0,1,7,65,34,67,34,23,24,67,54,43,]]) 

classes = model.predict(X_test_new, batch_size=16) 
print(classes) 

Benim çıkış sağ boyuttur, ama bana 0-1 yüzen veriyor:

Şu anda bu var. Sanırım bunun nedeni hala ikili sınıflamayı arıyor. Bunu nasıl düzelteceğini bilen var mı?

(X_train, y_train), (X_test, y_test), maxlen, word_ids, tags_ids = prep_model(
    nb_words=nb_words, test_len=75) 

W = (y_train > 0).astype('float') 

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.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', 
       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=W) 
+0

Verilerinizin küçük bir örneğini yükler misiniz? Modelin nasıl çalıştığını daha iyi anlamada yardımcı olur. Mümkün değilse, ham verilerinizin nasıl göründüğüne ve modeli beslemeden önce veri ön işleme için neler yaptığınıza dair biraz bilgi verebilir misiniz? –

cevap

4

Çözüldü:

Sadece etiketleri her ikili diziler olduğundan emin olun

ÇÖZÜLDÜ. Ana konu, ikili sınıflar olarak sınıflandırma kategorileri için verileri yeniden şekillendiriyordu. Ayrıca, TimeDistributed ve return_sequences değerini True olarak kullanır.

+0

Çalışma kodunu eklemeniz mümkün mü? thx – PSNR

+0

Elbette, sadece düzenlemelerin üzerine bakın. – ChrisDH

+0

Teşekkürler! Katıştırma katmanında 'mask_zero = True' kullandığımızda, sanırım tüm aşağıdaki katmanlar kayıp, doğruluk vb. Ve sanırım çıktı katmanındaki nb_classes'ın sınıf + 1 olması gerekir (yani, ikili sınıflandırma problemi için 3'tür)? Tekrar teşekkürler! – PSNR