<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Copyright 2018 The TensorFlow Authors.
Step1:  使用 tf.data 加载文本数据
<table class="tfo-notebook-buttons" align="left">
  <td>
    <a target="_blank" href="https
Step2:  三个版本的翻译分别来自于
Step3:  将文本加载到数据集中
迭代整个文件，将整个文件加载到自己的数据集中。
每个样本都需要单独标记，所以请使用 tf.data.Dataset.map 来为每个样本设定标签。这将迭代数据集中的每一个样本并且返回（ example, label ）对。
Step4:  将这些标记的数据集合并到一个数据集中，然后对其进行随机化操作。
Step5:  你可以使用 tf.data.Dataset.take 与 print 来查看 (example, label) 对的外观。numpy 属性显示每个 Tensor 的值。
Step6:  将文本编码成数字
机器学习基于的是数字而非文本，所以字符串需要被转化成数字列表。
为了达到此目的，我们需要构建文本与整数的一一映射。
建立词汇表
首先，通过将文本标记为单独的单词集合来构建词汇表。在 TensorFlow 和 Python 中均有很多方法来达成这一目的。在本教程中
Step7:  样本编码
通过传递 vocabulary_set 到 tfds.features.text.TokenTextEncoder 来构建一个编码器。编码器的 encode 方法传入一行文本，返回一个整数列表。
Step8:  你可以尝试运行这一行代码并查看输出的样式。
Step9:  现在，在数据集上运行编码器（通过将编码器打包到 tf.py_function 并且传参至数据集的 map 方法的方式来运行）。
Step10:  将数据集分割为测试集和训练集且进行分支
使用 tf.data.Dataset.take 和 tf.data.Dataset.skip 来建立一个小一些的测试数据集和稍大一些的训练数据集。
在数据集被传入模型之前，数据集需要被分批。最典型的是，每个分支中的样本大小与格式需要一致。但是数据集中样本并不全是相同大小的（每行文本字数并不相同）。因此，使用 tf.data.Dataset.padded_batch（而不是 batch ）将样本填充到相同的大小。
Step11:  现在，test_data 和 train_data 不是（ example, label ）对的集合，而是批次的集合。每个批次都是一对（多样本, 多标签 ），表示为数组。
Step12:  由于我们引入了一个新的 token 来编码（填充零），因此词汇表大小增加了一个。
Step13:  建立模型
Step14:  第一层将整数表示转换为密集矢量嵌入。更多内容请查阅 Word Embeddings 教程。
Step15:  下一层是 LSTM 层，它允许模型利用上下文中理解单词含义。 LSTM 上的双向包装器有助于模型理解当前数据点与其之前和之后的数据点的关系。
Step16:  最后，我们将获得一个或多个紧密连接的层，其中最后一层是输出层。输出层输出样本属于各个标签的概率，最后具有最高概率的分类标签即为最终预测结果。
Step17:  最后，编译这个模型。对于一个 softmax 分类模型来说，通常使用 sparse_categorical_crossentropy 作为其损失函数。你可以尝试其他的优化器，但是 adam 是最常用的。
Step18:  训练模型
利用提供的数据训练出的模型有着不错的精度（大约 83% ）。
<ASSISTANT_TASK:>
Python Code:
#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
Explanation: Copyright 2018 The TensorFlow Authors.
End of explanation
import tensorflow as tf
import tensorflow_datasets as tfds
import os
Explanation: 使用 tf.data 加载文本数据
<table class="tfo-notebook-buttons" align="left">
  <td>
    <a target="_blank" href="https://tensorflow.google.cn/tutorials/load_data/text"><img src="https://tensorflow.google.cn/images/tf_logo_32px.png" />在 TensorFlow.org 上查看</a>
  </td>
  <td>
    <a target="_blank" href="https://colab.research.google.com/github/tensorflow/docs-l10n/blob/master/site/zh-cn/tutorials/load_data/text.ipynb"><img src="https://tensorflow.google.cn/images/colab_logo_32px.png" />在 Google Colab 上运行</a>
  </td>
  <td>
    <a target="_blank" href="https://github.com/tensorflow/docs-l10n/blob/master/site/zh-cn/tutorials/load_data/text.ipynb"><img src="https://tensorflow.google.cn/images/GitHub-Mark-32px.png" />查看 GitHub 上的资源</a>
  </td>
  <td>
    <a href="https://storage.googleapis.com/tensorflow_docs/docs-l10n/site/zh-cn/tutorials/load_data/text.ipynb"><img src="https://tensorflow.google.cn/images/download_logo_32px.png" />下载 notebook</a>
  </td>
</table>
Note: 我们的 TensorFlow 社区翻译了这些文档。因为社区翻译是尽力而为， 所以无法保证它们是最准确的，并且反映了最新的
官方英文文档。如果您有改进此翻译的建议， 请提交 pull request 到
tensorflow/docs GitHub 仓库。要志愿地撰写或者审核译文，请加入
docs-zh-cn@tensorflow.org Google Group。
本教程为你提供了一个如何使用 tf.data.TextLineDataset 来加载文本文件的示例。TextLineDataset 通常被用来以文本文件构建数据集（原文件中的一行为一个样本) 。这适用于大多数的基于行的文本数据（例如，诗歌或错误日志) 。下面我们将使用相同作品（荷马的伊利亚特）三个不同版本的英文翻译，然后训练一个模型来通过单行文本确定译者。
环境搭建
End of explanation
DIRECTORY_URL = 'https://storage.googleapis.com/download.tensorflow.org/data/illiad/'
FILE_NAMES = ['cowper.txt', 'derby.txt', 'butler.txt']
for name in FILE_NAMES:
  text_dir = tf.keras.utils.get_file(name, origin=DIRECTORY_URL+name)
  
parent_dir = os.path.dirname(text_dir)
parent_dir
Explanation: 三个版本的翻译分别来自于:
William Cowper — text
Edward, Earl of Derby — text
Samuel Butler — text
本教程中使用的文本文件已经进行过一些典型的预处理，主要包括删除了文档页眉和页脚，行号，章节标题。请下载这些已经被局部改动过的文件。
End of explanation
def labeler(example, index):
  return example, tf.cast(index, tf.int64)  
labeled_data_sets = []
for i, file_name in enumerate(FILE_NAMES):
  lines_dataset = tf.data.TextLineDataset(os.path.join(parent_dir, file_name))
  labeled_dataset = lines_dataset.map(lambda ex: labeler(ex, i))
  labeled_data_sets.append(labeled_dataset)
Explanation: 将文本加载到数据集中
迭代整个文件，将整个文件加载到自己的数据集中。
每个样本都需要单独标记，所以请使用 tf.data.Dataset.map 来为每个样本设定标签。这将迭代数据集中的每一个样本并且返回（ example, label ）对。
End of explanation
BUFFER_SIZE = 50000
BATCH_SIZE = 64
TAKE_SIZE = 5000
all_labeled_data = labeled_data_sets[0]
for labeled_dataset in labeled_data_sets[1:]:
  all_labeled_data = all_labeled_data.concatenate(labeled_dataset)
  
all_labeled_data = all_labeled_data.shuffle(
    BUFFER_SIZE, reshuffle_each_iteration=False)
Explanation: 将这些标记的数据集合并到一个数据集中，然后对其进行随机化操作。
End of explanation
for ex in all_labeled_data.take(5):
  print(ex)
Explanation: 你可以使用 tf.data.Dataset.take 与 print 来查看 (example, label) 对的外观。numpy 属性显示每个 Tensor 的值。
End of explanation
tokenizer = tfds.features.text.Tokenizer()
vocabulary_set = set()
for text_tensor, _ in all_labeled_data:
  some_tokens = tokenizer.tokenize(text_tensor.numpy())
  vocabulary_set.update(some_tokens)
vocab_size = len(vocabulary_set)
vocab_size
Explanation: 将文本编码成数字
机器学习基于的是数字而非文本，所以字符串需要被转化成数字列表。
为了达到此目的，我们需要构建文本与整数的一一映射。
建立词汇表
首先，通过将文本标记为单独的单词集合来构建词汇表。在 TensorFlow 和 Python 中均有很多方法来达成这一目的。在本教程中:
迭代每个样本的 numpy 值。
使用 tfds.features.text.Tokenizer 来将其分割成 token。
将这些 token 放入一个 Python 集合中，借此来清除重复项。
获取该词汇表的大小以便于以后使用。
End of explanation
encoder = tfds.features.text.TokenTextEncoder(vocabulary_set)
Explanation: 样本编码
通过传递 vocabulary_set 到 tfds.features.text.TokenTextEncoder 来构建一个编码器。编码器的 encode 方法传入一行文本，返回一个整数列表。
End of explanation
example_text = next(iter(all_labeled_data))[0].numpy()
print(example_text)
encoded_example = encoder.encode(example_text)
print(encoded_example)
Explanation: 你可以尝试运行这一行代码并查看输出的样式。
End of explanation
def encode(text_tensor, label):
  encoded_text = encoder.encode(text_tensor.numpy())
  return encoded_text, label
def encode_map_fn(text, label):
  # py_func doesn't set the shape of the returned tensors.
  encoded_text, label = tf.py_function(encode, 
                                       inp=[text, label], 
                                       Tout=(tf.int64, tf.int64))
  # `tf.data.Datasets` work best if all components have a shape set
  #  so set the shapes manually: 
  encoded_text.set_shape([None])
  label.set_shape([])
  return encoded_text, label
all_encoded_data = all_labeled_data.map(encode_map_fn)
Explanation: 现在，在数据集上运行编码器（通过将编码器打包到 tf.py_function 并且传参至数据集的 map 方法的方式来运行）。
End of explanation
train_data = all_encoded_data.skip(TAKE_SIZE).shuffle(BUFFER_SIZE)
train_data = train_data.padded_batch(BATCH_SIZE)
test_data = all_encoded_data.take(TAKE_SIZE)
test_data = test_data.padded_batch(BATCH_SIZE)
Explanation: 将数据集分割为测试集和训练集且进行分支
使用 tf.data.Dataset.take 和 tf.data.Dataset.skip 来建立一个小一些的测试数据集和稍大一些的训练数据集。
在数据集被传入模型之前，数据集需要被分批。最典型的是，每个分支中的样本大小与格式需要一致。但是数据集中样本并不全是相同大小的（每行文本字数并不相同）。因此，使用 tf.data.Dataset.padded_batch（而不是 batch ）将样本填充到相同的大小。
End of explanation
sample_text, sample_labels = next(iter(test_data))
sample_text[0], sample_labels[0]
Explanation: 现在，test_data 和 train_data 不是（ example, label ）对的集合，而是批次的集合。每个批次都是一对（多样本, 多标签 ），表示为数组。
End of explanation
vocab_size += 1
Explanation: 由于我们引入了一个新的 token 来编码（填充零），因此词汇表大小增加了一个。
End of explanation
model = tf.keras.Sequential()
Explanation: 建立模型
End of explanation
model.add(tf.keras.layers.Embedding(vocab_size, 64))
Explanation: 第一层将整数表示转换为密集矢量嵌入。更多内容请查阅 Word Embeddings 教程。
End of explanation
model.add(tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64)))
Explanation: 下一层是 LSTM 层，它允许模型利用上下文中理解单词含义。 LSTM 上的双向包装器有助于模型理解当前数据点与其之前和之后的数据点的关系。
End of explanation
# 一个或多个紧密连接的层
# 编辑 `for` 行的列表去检测层的大小
for units in [64, 64]:
  model.add(tf.keras.layers.Dense(units, activation='relu'))
# 输出层。第一个参数是标签个数。
model.add(tf.keras.layers.Dense(3, activation='softmax'))
Explanation: 最后，我们将获得一个或多个紧密连接的层，其中最后一层是输出层。输出层输出样本属于各个标签的概率，最后具有最高概率的分类标签即为最终预测结果。
End of explanation
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
Explanation: 最后，编译这个模型。对于一个 softmax 分类模型来说，通常使用 sparse_categorical_crossentropy 作为其损失函数。你可以尝试其他的优化器，但是 adam 是最常用的。
End of explanation
model.fit(train_data, epochs=3, validation_data=test_data)
eval_loss, eval_acc = model.evaluate(test_data)
print('\nEval loss: {}, Eval accuracy: {}'.format(eval_loss, eval_acc))
Explanation: 训练模型
利用提供的数据训练出的模型有着不错的精度（大约 83% ）。
End of explanation
<END_TASK>