2016-06-14 6 views
6

私はIMDB exampleに基づいてBLSTMを実行していますが、私のバージョンは分類ではなく、ラベルのシーケンス予測です。簡単にするため、POSタギングモデルとして扱うことができます。入力は単語の文、出力はタグです。この例で使用される構文は、model.addを使用せず、シーケンスを開始する点で、他のほとんどのKerasの例と構文が少し異なります。このわずかに異なる構文でマスクレイヤーを追加する方法を理解できません。ケラス用マスキングBLSTM

モデルを実行してテストしたところ、うまく動作しましたが、パディングである0の精度を予測して評価しています。ここでは、コードです:

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:

私はこのPRを合併し、それは埋め込み層にmask_zero=Trueと協力してしまいました。しかし、私はモデルのひどいパフォーマンスを見て、出力でマスキングする必要があるのを見て、今実現しています。他の人はmodel.fit行の代わりにsample_weightを使用するように提案しています。 0を無視するにはどうすればいいですか?

UPDATE 2:

だから私はthisを読み、1と0の行列としてsample_weightを考え出しました。私はそれが動作している可能性があると思ったが、私の精度は%50前後で止まってしまった。そして、パッディングされた部分を予測しようとしているが、sample_weightを使用する前の問題と同様に、

現在のコード:

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

これは古い質問ですが、これを解決しましたか?私は同じ段階です...私は[精度は 'sample_weight'を考慮していません(https://github.com/fchollet/keras/issues/1642)と私のテストによると、マスキング(実際にマスキングを使用すると、私はまだ動かないほどの精度の値が得られます)。おそらく機能的APIを使用して、精度で2番目の出力を構築することになります。 – jdehesa

+0

この問題を再検討し、現在のKerasコードに関して簡潔にしていただければ幸いです。 – Seanny123

答えて

1

あなたはこの問題を解決しましたか?パディングされた値と単語インデックスをコードで扱う方法は、私にはあまり明確ではありません。どのような単語インデックスは1から始まり、https://keras.io/layers/embeddings/に応じ

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

代わりの

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

を定義させるでしょうか?