Как сформировать входные данные для использования вложенных слов BPEmb в модели Keras LSTM для генерации текста? - PullRequest
0 голосов
/ 27 мая 2019

Я пытаюсь обучить модель Keras / Tensorflow LSTM в Колаборатории Google для генерации текста из подслов с использованием вложений BPEmb .

Насколько я понимаю, вложения - это модель генезиса, которая производит 300-мерные векторы для кусков подслов.

Моя модель предназначена для использования последовательностей k вложений для прогнозирования k+1 -го внедрения, которое я затем декодирую, используя BPEmb.similar_by_vector(), а затем BPEmb.decode().

У меня есть ~ 2,5M-встраиваемый набор данных, поэтому для длины последовательности 100 мне нужно обработать 2.5 * 10^8 * 300 значения. Чтобы избежать переполнения памяти, я использую функцию генератора следующим образом:

# this reads my data into a huge text file
text = read_data(DATA_FILES) 
bpe_uk = BPEmb(lang='uk', dim=EMB_DIM)
vectors = bpe_uk.embed(text)

def training_generator2(vectors, k=100, batch_size=1024):
    """Dynamically feed training sequences for a recurrent neural network model:
    Output shape:
    x = (batch_size, k, dim)
    y = (300)
    """

    i = 0  # offset in the data set
    while i+k < len(vectors):

        # init empty batch
        x = []
        for sample_id in range(0, batch_size):

          x.append(vectors[i:i+k])
          y = vectors[i+k]
          i+=1
        yield (x, y)

g = training_generator2(vectors, 100, 128)
v = next(g)

np.shape(v[0])
>>> (128, 100, 300) # the X of the training pair is 128 batches of 100 sequences of 300-dim vectors

np.shape(v[1])
>>> (300, ) # the Y of the training pair is just one 300-dim vector

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


EMBEDDING_DIM = EMB_DIM
SHAPE = (SEQ_LEN, EMB_DIM)

def lstm_model(seq_len=SEQ_LEN, batch_size=None, stateful=True):
  """Language model: predict the next word given the current word."""
  source = tf.keras.Input(
      name='seed', shape=(seq_len, EMBEDDING_DIM), batch_size=batch_size, dtype=tf.float32)

  lstm_1 = tf.keras.layers.LSTM(EMBEDDING_DIM, stateful=stateful, return_sequences=True)(source)
  lstm_2 = tf.keras.layers.LSTM(EMBEDDING_DIM, stateful=stateful, return_sequences=True)(lstm_1)
  predicted_char = tf.keras.layers.TimeDistributed(tf.keras.layers.Dense(300, activation='softmax'))(lstm_2)
  model = tf.keras.Model(inputs=[source], outputs=[predicted_char])
  model.compile(
      optimizer=tf.train.RMSPropOptimizer(learning_rate=0.01),
      loss='sparse_categorical_crossentropy',
      metrics=['sparse_categorical_accuracy'])
  return model

model = lstm_model(seq_len=SEQ_LEN, batch_size=128, stateful=False)
model.summary()
Layer (type)                 Output Shape              Param #   
=================================================================
seed (InputLayer)            (128, 100, 300)           0         
_________________________________________________________________
lstm_3 (LSTM)                (128, 100, 300)           721200    
_________________________________________________________________
lstm_4 (LSTM)                (128, 100, 300)           721200    
_________________________________________________________________
time_distributed_1 (TimeDist (128, 100, 300)           90300     
=================================================================
Total params: 1,532,700
Trainable params: 1,532,700
Non-trainable params: 0
_________________________________________________________________

Когда я пытаюсь тренировать эту модель так:

tf.keras.backend.clear_session()

training_model = lstm_model(seq_len=SEQ_LEN, batch_size=128, stateful=False)

tpu_model = tf.contrib.tpu.keras_to_tpu_model(
    training_model,
    strategy=tf.contrib.tpu.TPUDistributionStrategy(
        tf.contrib.cluster_resolver.TPUClusterResolver(TPU_WORKER)))

tpu_model.fit_generator(
    training_generator2(vectors, k=100, batch_size=128),
    steps_per_epoch=100,
    epochs=10,
)

Я получаю следующее сообщение об ошибке:


ValueError: Error when checking input: expected seed to have 3 dimensions, but got array with shape (100, 300)

Похоже, данные обучения должны быть преобразованы во что-то вроде (100, 300, 1), причем окончательные значения в основном являются массивами одного значения. Это правильно? И если да, то как это сделать?

Обратите внимание, что я новичок в Keras и в целом глубоко изучаю, поэтому может возникнуть несколько проблем с этой настройкой, включая определение модели. Любые отзывы или предложения будут приветствоваться!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...