Как указать входные данные со списком массивов для встраиваемого слоя в Keras?

#python #tensorflow #keras #word2vec #word-embedding

#python #tensorflow #keras #word2vec #word-встраивание

Вопрос:

Я пытаюсь выполнить генерацию текста на уровне word и застрял с последующей проблемой:

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

    tokenized_seq = [[w2v_model.wv.vocab[word].index for word in w2v_data[i]] for i in range(len(w2v_data))]
   x_seq = []
   y_seq = []

   for seq in tokenized_seq:
      x_seq.append(seq[:-1])
      y_seq.append([seq[-1]])
  

Итак, я иду вдоль последовательности (кодированные слова, используемые в word2vec) с переходящим окном фиксированного размера (маркированный _seq — это список последовательностей фиксированной длины).

Посмотрите пример:

Блок кода:

 print(x_seq[0], '->', y_seq[0])  
print(' '.join([w2v_model.wv.index2word[i] for i in x_seq[0]]), '->', w2v_model.wv.index2word[y_seq[0].pop()]) 
  

Вывод:

 [608, 1661, 1, 4260, 1, 3, 2978, 741, 0, 153, 740, 1, 12004] -> [109]
часть первая . i . — eh bien , mon prince . gênes -> et
  

Итак, тогда я пытаюсь ввести все вышеперечисленное для встраиваемого слоя.

 model = Sequential()
model.add(Embedding(input_dim=vocab_size,
                    output_dim=emdedding_size,
                    input_length=avg_sent_len-1,
                    weights=[predtrained_weights]
                    trainable=False))

model.add(Bidirectional(LSTM(units=128)))

model.add(Dense(units=vocab_size, activation='softmax'))

model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])

history = model.fit(x_seq, y_seq,
                   epochs=10,
                   batch_size=128,
                   validation_split=0.2,
                   verbose=2)

  

Параметрами встраивания являются:

 predtrained_weights = w2v_model.wv.vectors
vocab_size, emdedding_size = w2v_model.wv.vectors.shape
  

avg_sent_len является ли длина каждой последовательности в x_seq

Модель компилируется хорошо, но при установке я получаю следующую ошибку:

 ValueError: Error when checking target: expected dense_40 to have shape (31412,) but got array with shape (223396,) 
  

(31412,) является vocab_size
223396 — это x_seq или y_seq длина (количество входных последовательностей)
Итак, кто-нибудь может мне помочь?

Ответ №1:

Ваши входные данные x_seq должны быть одним массивом numpy shape (batch_size, seq_len) . Попробуйте добавить x_seq = np.array(x_seq) .

Комментарии:

1. Спасибо, это помогло, но у меня все еще есть проблемы с встраиванием входных данных. Ожидается, что входные данные будут иметь форму vocab_size , но доказанный ввод (и я думаю, это правильный путь) является x_seq.shape , что не одно и то же. Итак, я немного запутался

2. Вероятно, проблема в слое BiLSTM, следующем за вашим слоем встраивания. input_shape Этот слой должен быть (seq_len, embedding_size) , а не (vocab_size, seq_len) таким, как вы написали в своем коде. Если это не помогло, пожалуйста, укажите сообщение об ошибке, которое вы получаете.

3.Я пытался использовать оба неуказанных LSTM: model.add(Bidirectional(LSTM(units=128)) l ike в примерах bunch и указать форму ввода, как вы сказали: model.add(Bidirectional(LSTM(units=128, input_shape=(len(x_seq), emdedding_size)))) И оба способа не помогли. Я получаю сообщение об ошибке: ValueError: Error when checking target: expected dense_34 to have shape (31412,) but got array with shape (223396,) 31412, это размер vocab, 223396 — длина x_seq (ввода)

4. Эта ошибка связана с целевыми объектами ( y_seq ), а не с входными данными ( x_seq ). Ваша цель должна иметь форму (batch_size, vocab_size) , где каждая из строк является одной с горячим кодированием. И вы действительно можете просто исключить input_shape из слоя LSTM.

5. Если вы используете categorical_crossentropy as loss, ваши метки определенно должны быть в горячем кодировании. В качестве альтернативы вы можете использовать sparse_categorical_crossentropy . В этом случае ваши метки должны иметь форму (batch_size, 1) и не должны быть закодированы горячим способом. Например, следующие фиктивные данные будут работать с разреженной категориальной кроссэнтропией: x_seq = np.random.rand(n_samples, seq_len) и y_seq = np.random.randint(0, vocab_size, n_samples).reshape((-1,1)) .