python - 使用 Tensorflow 模型正确构建文本数据以生成文本

标签 python tensorflow machine-learning keras recurrent-neural-network

我正在尝试训练我的模型以生成不再超过 210 个字符的句子。从我读到的内容来看,我只看到了对“连续”文本的训练。就像一本书。不过,我正在尝试在单个句子上训练我的模型。

我对 tensorflow 和机器学习还很陌生,所以现在我可以训练我的模型,但它会生成垃圾、看似随机的文本。我有 10,000 个句子,所以我认为我有足够的数据。

我的数据概览

结构[['SENTENCE'], ['SENTENCE2']...]

数据准备

tokenizer = keras.preprocessing.text.Tokenizer(num_words=209, lower=False, char_level=True, filters='#$%&()*+-<=>@[\\]^_`{|}~\t\n')
tokenizer.fit_on_texts(df['title'].values)
df['encoded_with_keras'] = tokenizer.texts_to_sequences(df['title'].values)

dataset = df['encoded_with_keras'].values
dataset = tf.keras.preprocessing.sequence.pad_sequences(dataset, padding='post')

dataset = dataset.flatten()

dataset = tf.data.Dataset.from_tensor_slices(dataset)

sequences = dataset.batch(seq_len+1, drop_remainder=True)

def create_seq_targets(seq):
    input_txt = seq[:-1]
    target_txt = seq[1:]
    return input_txt, target_txt

dataset = sequences.map(create_seq_targets)

dataset = dataset.shuffle(buffer_size).batch(batch_size, drop_remainder=True)

型号

def create_model(vocab_size, embed_dim, rnn_neurons, batch_size):
    model = Sequential()
    model.add(Embedding(vocab_size, embed_dim, batch_input_shape=[batch_size, None],input_length=209, mask_zero=True))
    model.add(LSTM(rnn_neurons, return_sequences=True, stateful=True,))
    model.add(Dropout(0.2))
    model.add(Dense(258, activation='relu'))
    model.add(Dropout(0.2))
    model.add(Dense(128, activation='relu'))
    model.add(Dropout(0.2))
    model.add(Dense(vocab_size, activation='softmax'))
    model.compile(optimizer='adam', loss="sparse_categorical_crossentropy")
    return model

当我给模型一个开始的序列时,我得到了绝对的废话,最终模型预测了一个不在 char_index 映射中的 0。

编辑

文本生成


epochs = 2

# Directory where the checkpoints will be saved
checkpoint_dir = './training_checkpoints'
# Name of the checkpoint files
checkpoint_prefix = os.path.join(checkpoint_dir, "ckpt_{epoch}")

checkpoint_callback=tf.keras.callbacks.ModelCheckpoint(
    filepath=checkpoint_prefix,
    save_weights_only=True)


model = create_model(vocab_size = vocab_size,
  embed_dim=embed_dim,
  rnn_neurons=rnn_neurons,
  batch_size=1)

model.load_weights(tf.train.latest_checkpoint(checkpoint_dir))

model.build(tf.TensorShape([1, None]))

def generate_text(model, start_string):
  num_generate = 200

  input_eval = [char_2_index[s] for s in start_string]
  input_eval = tf.expand_dims(input_eval, 0)

  text_generated = []

  temperature = 1

  # model.reset_states()
  for i in range(num_generate):
      print(text_generated)
      predictions = model(input_eval)

      predictions = tf.squeeze(predictions, 0)

      predictions = predictions / temperature

      predicted_id = tf.random.categorical(predictions, num_samples=1)[-1,0].numpy()
      print(predicted_id)

      input_eval = tf.expand_dims([predicted_id], 0)

      text_generated.append(index_2_char[predicted_id])

  return (start_string + ''.join(text_generated))

最佳答案

乍一看,有一些事情必须改变。

  • 分词器必须具有num_words = vocab_size
  • 一开始(没有深入分析),我无法想象如果数据集的结构可能正确,为什么要展平数据集并获取切片
  • 如果您不希望“第 2 批是第 1 批的续集”,则不能使用 stateful=True,您有单独的句子,因此 stateful=False 。 (除非你通过手动训练循环正确训练并重置每个批处理的状态,这在训练阶段是不必要的麻烦)

您需要目视检查的内容:

输入数据必须采用如下格式:

[
    [1,2,3,6,10,4,10, ...up to sentence length - 1...],
    [5,6,3,6,7,3,11,... up to sentence length - 1...],
    .... up to number of sentences ...
]

输出数据必须是:

[
    [2,3,6,10,4,10,15 ...], #equal to input data, shifted by 1
    [6,3,6,7,3,11,13, ...],
    ...
]

打印其中的几行,以检查它们是否按预期正确进行了预处理。

培训将变得容易:

model.fit(input_data, output_data, epochs=....)

是的,您的模型将预测零,因为您的数据中有零,这并不奇怪:您做了一个 pad_sequences
在这种情况下,您可以将零解释为“句子结束”,因为您进行了 'post' 填充。当你的模型给你一个零时,它决定它生成的句子应该在该点结束 - 如果它训练有素,它可能会从此时开始继续为该句子输出零。

<小时/>

生成新句子

这部分更复杂,您需要重写模型,现在是stative=True,并将权重从训练好的模型转移到这个新模型。

在执行任何操作之前,请调用 model.reset_states()

您需要手动喂入形状为(number_of_sentences=batch_size, 1)的批处理。这将是它将生成的每个句子的“第一个字符”。输出将是每个句子的“第二个字符”。

获取此输出并将其输入模型。它将生成每个句子的“第三个字符”。等等。

当所有输出都为零时,所有句子都已完全生成,您可以停止循环。

在尝试生成一批新的句子之前再次调用model.reset_states()

<小时/>

您可以在这里找到此类预测的示例:https://stackoverflow.com/a/50235563/2097240

关于python - 使用 Tensorflow 模型正确构建文本数据以生成文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60170063/

相关文章:

python - 在 Tensorflow-lite 中输入具有动态尺寸的图像

MATLAB 中与算法无关的超参数网格搜索

r - r 中的最佳簇数

python - 使用 Hough 变换、OpenCV 和 python 进行平行线检测

python - 从坐标质心获取最近的 pandas df 坐标

python - 安装GDAL时出错

python - tensorflow mnist 示例精度没有增加

python - 属性错误 : 'tensorflow.python.framework.ops.EagerTensor' object has no attribute 'decode'

machine-learning - 如何根据偏差和权重计算神经元的输出? [神经网络]

python - 如何使用 Django 连接