赞
踩
字符级 RNN 是一种递归神经网络,它在字符级别处理输入数据,而不是像传统 RNN 那样在单词级别处理输入数据。我们可以将它们用于各种自然语言处理任务,包括语言翻译、文本分类和文本生成。然而,字符级 RNN 存在局限性,例如在某些任务上比词级模型更长的训练时间和更低的整体性能。
在本文中,我们将使用 Tensorflow 构建字符级递归神经网络 (RNN)。RNN 是一种神经网络,非常适合处理文本等顺序数据。字符级 RNN 对单个字符而不是整个单词进行操作,允许它一次处理和文本生成一个字符。 以下是我们将遵循的步骤的细分:
以下是我们将在本文中介绍的一些主要主题:
在继续本教程之前,对这些主题有一个基本的了解会很有帮助。如果您仍然熟悉这些主题,请考虑在继续之前阅读更多内容。
要构建字符级 RNN,我们将遵循以下步骤:
输出:
但是,一旦你完成了这篇文章,你应该有一个字符级的 RNN 模型,可以一次生成一个字符。您可以使用此模型生成与训练数据类似的文本,或创建新的原始文本。
若要遵循提供的代码,需要安装以下库和模块:
使用 TensorFlow 构建字符级循环神经网络 (RNN) 是一个多步骤过程。本指南将概述所涉及的步骤,从较简单的步骤开始,逐步发展到更复杂的步骤。
首先,我们将导入必要的库。我们将使用 TensorFlow 和 NumPy。
- import tensorflow as tf
- import numpy as np
接下来,我们将加载数据集。我们将使用为此示例下载的莎士比亚数据集的预处理版本。
- with open('shakespeare_input.txt', 'r') as f:
- text = f.read()
这可以使用 python 的内置 set() 和 enumerate() 函数来完成,如下面的代码片段所示。set() 函数从文本中提取所有唯一字符,而 enumerate() 函数为每个字符分配一个唯一的整数。结果是两个字典:一个将字符映射到整数 (char_to_int),另一个将整数映射到字符 (int_to_char)。我们稍后将使用这些字典对文本数据进行编码和解码,作为 RNN 的输入和输出。
- chars = sorted(list(set(text)))
- char_to_int = {ch:i for i, ch in enumerate(chars)}
- int_to_char = {i:ch for i, ch in enumerate(chars)}
第一步是创建唯一字符列表,并将每个字符映射到唯一整数。这可以使用 python 内置的 set() 和 enumerate() 函数来完成。然后,我们通过在文本上创建一个滑动窗口来创建训练示例和标签,其中输入是字符序列,标签是序列中的下一个字符。我们将输入序列填充为相同的长度,并将标签转换为确定的格式。
- # Set the maximum sequence length (max_len) to be the length of the longest sequence
- max_len = max([len(s) for s in text])
-
- # Create training examples and labels
- X = []
- y = []
-
- for i in range(0, len(text)-max_len, 1):
- X.append([char_to_int[ch] for ch in text[i:i+max_len]])
- y.append(char_to_int[text[i+max_len]])
现在我们有了训练示例和标签,我们需要填充它们,使它们都具有相同的长度。为此,我们将使用零填充。
- # Pad the examples
- X = tf.keras.preprocessing.sequence.pad_sequences(X, maxlen=max_len, padding='post')
-
- # Convert labels to categorical format
- y = tf.keras.utils.to_categorical(y)
我们使用 TensorFlow 的 Sequential API 来构建用于文本生成的 LSTM 模型,并依次添加一个嵌入层、一个 LSTM 层和一个具有 softmax 激活的 Dense 层。Embedding 层将输入数据转换为密集向量表示,LSTM 层处理序列数据,Dense 层生成输出。
- # Define the model architecture
- model = tf.keras.Sequential()
- model.add(tf.keras.layers.Embedding(input_dim=len(chars), output_dim=64))
- model.add(tf.keras.layers.LSTM(units=128))
- model.add(tf.keras.layers.Dense(units=len(chars), activation='softmax'))
Embedding 层的输出维度应为数据集中唯一字符数,LSTM 层和 Dense 层的单位应相同。
编译模型后,我们现在可以开始训练了。
- # Train the model
- model.fit(X, y, epochs=100, batch_size=64)
训练模型后,我们现在可以将其用于文本生成。为此,我们将定义一个函数,该函数接受种子序列并生成指定数量的字符。
- def generate_text(seed, num_chars):
- # Initialize the generated text
- generated_text = seed
-
- # Encode the seed as integers
- encoded_seed = [char_to_int[ch] for ch in seed]
-
- # Pad the seed
- padded_seed = tf.keras.preprocessing.sequence.pad_sequences([encoded_seed], maxlen=max_len, padding='post')
-
- # Generate characters
- for i in range(num_chars):
- # Get the next character probabilities
- probs = model.predict(padded_seed)[0]
-
- # Get the index of the character with the highest probability
- index = np.argmax(probs)
-
- # Add the character to the generated text
- generated_text += int_to_char[index]
-
- # Update the padded seed with the latest character
- padded_seed = np.append(padded_seed[0][1:], index)
- padded_seed = tf.keras.preprocessing.sequence.pad_sequences([padded_seed], maxlen=max_len, padding='post')
-
- return generated_text
现在,我们可以通过调用带有种子序列和要生成的字符数的 generate_text 函数来生成文本。
- # Generate text
- generated_text = generate_text('ROMEO: ', 100)
- print(generated_text)
输出:
ROMEO: Oh, that thou mightst as soon forget To pay thy part, as I to keep the debt unpaid.
您可以通过多种方式扩展项目,以添加更多特性和功能。以下是一些想法:
- RNN 在处理文本等顺序数据方面非常有效。
- LSTM 细胞可以通过允许 RNN 保留长期记忆来帮助提高 RNN 的性能。
- 我们必须先对文本数据进行预处理,然后才能使用它来训练模型。
- Tensorflow 为构建和训练 RNN 提供了一个方便而强大的工具包。
构建字符级 RNN 是了解神经网络和自然语言处理的更多信息的好方法,可以作为这些领域更高级项目的起点。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。