2017-02-02 2 views
6

Я закодировал sequence to sequence, изучая LSTM в keras самостоятельно, используя знания, полученные из веб-уроков и моих собственных интуиций. Я преобразовал свой образец текста в последовательности и затем дополнял функцию pad_sequence в keras.Как мы можем прокладывать текстовую последовательность в keras, используя pad_sequences?

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) 

После тщательно осмотра я нашел мою проложенная последовательность выглядит следующим образом

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

предположит ли проложенная последовательность выглядеть следующим образом? За исключением последнего столбца в массиве, остальные - все нули. Я думаю, что я допустил ошибку в заполнении текста до последовательности, и если да, то можете ли вы сказать мне, где я сделал ошибку?

ответ

6

Если вы хотите разметить на гольца, вы можете сделать это вручную, это не слишком сложно:

Сначала создать словарь для ваших персонажей:

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

Это будет ассоциировать отдельный номер для каждого символа в вашем txt. Символ с индексом 0 должен быть сохранен для заполнения.

Наличие обратного словаря будет полезно для декодирования вывода.

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

После того как вы это, вы можете сначала разделить текст в последовательности, скажем, вы хотите, чтобы иметь последовательности длины seq_len = 13:

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

ваш выход будет выглядеть следующим образом:

[[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]] 

Обратите внимание, что последняя последовательность не имеет одинаковую длину, вы можете отбросить ее или заполнить свою последовательность до max_len = 13, она добавит 0 к ней.

Вы можете построить свои цели Y таким же образом, сдвигая все на 1. :-)

Я надеюсь, что это помогает.

3

Проблема заключается в этой строке:

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

При установке такого раскола (по " "), из-за характер ваших данных, вы получите каждую последовательность, состоящую из одного слова. Вот почему ваши дополненные последовательности имеют только один ненулевой элемент. Для того, чтобы изменить эту попытку:

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

Благодарим за указание ошибки, но что это лучший способ решить эту проблему. Документы в [keras] (https://keras.io/preprocessing/text/#tokenizer) очень расплывчаты. – Eka

+0

Каковы ваши последовательности, разделенные? –

+0

моя последовательность выглядит примерно так: 'abcdefghijklmnabcdefghijklmn ..... mn' Я хочу отделить его как отдельные буквы 'a b c d e f g h i j k l m n ...', которые являются символами (последовательность символов для обучения последовательно) – Eka

Смежные вопросы