2017-02-02 48 views
6

Web öğreticiler ve kendi sezgilerimden edindiğim bilgileri kullanarak kendiminkine bir sequence to sequence öğrenme LSTM kodladım. Örnek metnimi sıralarına dönüştürdüm ve ardından keras'ta pad_sequence işlevini kullanarak doldurdum. Bir dikkatlice muayene sonrasında Metin dizisini pad_sequences kullanarak kerasta nasıl peki yapalım?

from keras.preprocessing.text import Tokenizer,base_filter 
from keras.preprocessing.sequence import pad_sequences 

def shift(seq, n): 
    n = n % len(seq) 
    return seq[n:] + seq[:n] 

txt="abcdefghijklmn"*100 

tk = Tokenizer(nb_words=2000, filters=base_filter(), lower=True, split=" ") 
tk.fit_on_texts(txt) 
x = tk.texts_to_sequences(txt) 
#shifing to left 
y = shift(x,1) 

#padding sequence 
max_len = 100 
max_features=len(tk.word_counts) 
X = pad_sequences(x, maxlen=max_len) 
Y = pad_sequences(y, maxlen=max_len) 

benim yastıklı dizisi bu

>>> X[0:6] 
array([[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4], 
     [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7]], dtype=int32) 
>>> X 
array([[ 0, 0, 0, ..., 0, 0, 1], 
     [ 0, 0, 0, ..., 0, 0, 3], 
     [ 0, 0, 0, ..., 0, 0, 2], 
     ..., 
     [ 0, 0, 0, ..., 0, 0, 13], 
     [ 0, 0, 0, ..., 0, 0, 12], 
     [ 0, 0, 0, ..., 0, 0, 14]], dtype=int32) 

benziyor yastıklı dizisi şöyle görünecek şekilde varsayalım mı bulundu? Dizideki son sütun dışında kalanlar sıfırdır. Sanırım metni sıraya dizmek için bazı hatalar yaptım ve eğer hata yaptığını bana söyleyebilir misin?

cevap

6

, bunu elle yapabilirsiniz, çok karmaşık değil:

Önce karakterler için bir kelime oluşturun:

txt="abcdefghijklmn"*100 
vocab_char = {k: (v+1) for k, v in zip(set(txt), range(len(set(txt))))} 
vocab_char['<PAD>'] = 0 

Bu, txt'nizdeki her karakter için ayrı bir sayı ilişkilendirir. Dolgu için indeks 0 olan karakter korunmalıdır. Çıktının kodunu çözmek için tersine kelime bilgisi kullanmak yararlı olacaktır. Bunu aldıktan sonra

rvocab = {v: k for k, v in vocab.items()} 

, önce, diziler metninizi bölmek Eğer uzunluk seq_len = 13 dizileri istiyorum söyleyebiliriz:

[[9, 12, 6, 10, 8, 7, 2, 1, 5, 13, 11, 4, 3], 
[14, 9, 12, 6, 10, 8, 7, 2, 1, 5, 13, 11, 4], 
..., 
[2, 1, 5, 13, 11, 4, 3, 14, 9, 12, 6, 10, 8], 
[7, 2, 1, 5, 13, 11, 4, 3, 14]] 
:

[[vocab_char[char] for char in txt[i:(i+seq_len)]] for i in range(0,len(txt),seq_len)] 

çıktı benzeyecek

Son dizinin aynı uzunlukta olmadığına dikkat edin, onu atabilir veya sıranızı max_len = 13'e getirebilirsiniz, 0'a ekleyecektir.

Sen 1. :-)

umarım bu yardımcı olur herşeyi kaydırarak, hedeflerinizi Y aynı yolu inşa edebilirsiniz.

3

sorun bu satırda geçerli:

tk = Tokenizer(nb_words=2000, filters=base_filter(), lower=True, split=" ") 

sen (" " tarafından) bu tür bölünmeyi ayarladığınızda nedeniyle verilerinizin doğası gereği, tek bir kelime oluşan her sırasını elde edersiniz. Bu nedenle, doldurulmuş dizileriniz yalnızca sıfır olmayan bir öğeye sahiptir. Bu deneyin değiştirmek için: Char tarafından tokenize istiyorsanız

txt="a b c d e f g h i j k l m n "*100 
+0

Hatayı bildirdiğiniz için teşekkür ederiz, ancak bunu çözmenin en iyi yolu nedir? [Keras] 'daki dokümanlar (https://keras.io/preprocessing/text/#tokenizer) çok belirsizdir. – Eka

+0

Sıralarınız neyle ayrılıyorsunuz? –

+0

Benim dizilim bu gibi bir şey gibi görünüyor abcdefghijklmnabcdefghijklmn ..... mn' Tek tek harfler olarak ayırmak istiyorum 'a b c d e f g h i j k lm n ... 'karakter olarak (sıra dizilişi öğrenme sırası) – Eka