Skip to content

95.基于TensorFlow训练和评估模型 ​

来源:语雀原文 | 整理日期:2026-09-22

示例代码

注:将ppt后缀名改为zip后解压

TensorFlow 是由 Google 开发 的开源机器学习框架,主要用于构建、训练和部署机器学习模型。它支持深度学习、传统机器学习和数值计算,适用于图像识别、自然语言处理(NLP)、推荐系统、强化学习等多种任务。

核心特性

  • 基于 数据流编程(Dataflow Programming),通过计算图(Computational Graph)描述计算流程。
  • 支持 GPU/TPU 加速,可在服务器、移动端、浏览器等多平台部署。
  • 提供丰富的工具和库(如 TensorBoard、TensorFlow Lite、TensorFlow.js),形成完整的生态系统。

核心概念

(1)张量(Tensor)

  • TensorFlow 中的基本数据结构,是多维数组的通用表示形式(如标量、向量、矩阵)。

  • 属性:

  • 形状(Shape):张量的维度(如 (3, 4) 表示 3 行 4 列的矩阵)。

  • 数据类型(DType):如 float32、int32 等。

(2)计算图(Computational Graph)

TensorFlow 将计算表示为有向图,其中节点代表运算,边代表数据流。通过构建计算图,可以将复杂的计算任务分解为多个简单的操作。

  • 由节点(操作)和边(张量流动)构成的静态图,描述计算流程。

  • 优点:

  • 支持高效的并行计算和分布式训练。

  • 可通过 TensorBoard 可视化计算图和训练过程。

(3)会话(session)

在 TensorFlow 中,使用会话来执行计算图。会话负责分配资源并执行操作,可以在本地机器或分布式环境中运行。

(4)变量与占位符

  • 变量(Variable):模型参数(如神经网络的权重和偏置),在训练中不断更新。
  • 占位符(Placeholder):输入数据的占位符,在运行时通过 feed_dict 传递数据(TensorFlow 1.x 特有,2.x 推荐使用 tf.function 和 @tf.function 装饰器)。

架构特点

  • 灵活性和可扩展性 :TensorFlow 提供了灵活的架构,可以在各种平台上运行,包括桌面设备、服务器和移动设备等多种设备。它的图(Graph)定义和会话(Session)执行分离的模式使得用户可以先构建一个计算图,这个计算图就像一个配方,描述了数据如何在各个操作节点之间流动和计算。然后在会话中执行这个图,这样就可以很方便地在不同的硬件设备上运行相同的计算图,实现跨平台的可扩展性。
  • 自动微分功能 :在机器学习中,计算梯度是优化模型参数的关键步骤。TensorFlow 内置了自动微分功能,它可以自动计算复杂神经网络模型中各个参数的梯度。例如,当构建一个深度神经网络时,只需要定义好网络的前向传播过程,TensorFlow 就能够通过自动微分机制自动计算出反向传播所需的梯度,大大简化了模型训练过程中的梯度计算工作。
  • 丰富的 API 和工具集 :TensorFlow 提供了丰富的 API,包括用于构建神经网络的各种层(如全连接层、卷积层、循环层等)、损失函数(如均方误差损失、交叉熵损失等)和优化器(如随机梯度下降、Adam 优化器等)。同时,它还配备了一系列工具,如 TensorBoard,用于可视化计算图、训练过程中的指标(如损失值、准确率等)和模型的性能分析,方便开发者进行调试和优化。

应用场景

  • 深度学习模型训练和部署 :TensorFlow 广泛应用于各种深度学习模型的训练,包括图像识别(如使用卷积神经网络识别图片中的物体)、自然语言处理(如使用循环神经网络或 Transformer 架构进行文本生成、机器翻译等)和语音识别等领域。在模型训练完成后,还可以通过 TensorFlow Serving 等工具将模型部署到生产环境中,用于实际的预测任务。
  • 强化学习 :在强化学习领域,TensorFlow 也被用来构建智能体。例如,在游戏 AI 的开发中,智能体可以通过 TensorFlow 构建的神经网络来学习如何在游戏中做出决策,以最大化累积奖励。它能够处理强化学习中复杂的策略网络和价值网络的训练和更新。
  • 自然语言处理(NLP):TensorFlow 提供了强大的文本处理和自然语言处理工具,可以用于构建情感分析、文本生成、机器翻译等应用。
  • 图像识别和计算机视觉:TensorFlow 提供了用于处理图像数据的功能,可以用于构建图像分类、目标检测、图像生成等视觉任务。

TensorFlow 与 PyTorch 对比

特性TensorFlowPyTorch
编程模型静态计算图(需先定义后执行)动态计算图(支持即时调试)
易用性适合工业级部署和分布式任务更灵活,适合快速原型开发
社区支持官方文档完善,生态工具丰富(如 TensorBoard)开发者友好,社区活跃度高
分布式训练原生支持多 GPU/TPU 和分布式框架需借助第三方库(如 Ray)

官方文档与教程:

TensorFlow 是一个功能强大、灵活且易于使用的机器学习框架,适用于各种不同领域的数据分析和模型构建任务。TensorFlow 凭借其强大的功能和生态系统,成为深度学习研究和应用的首选工具之一。无论是学术研究还是工业落地,它都能提供高效、灵活的解决方案。

使用 TensorFlow 快速训练一个模型,使用 pipeline() 进行推理,使用 AutoClass 加载一个预训练模型和预处理器

在开始之前,确保你已经安装了所有必要的库:

plain
!pip install transformers datasets evaluate accelerate

使用 Tensorflow 训练 ​

所有模型都是标准的 tf.keras.Model,所以你可以通过 Keras API 实现在 Tensorflow 中训练。🤗 Transformers 提供了 prepare_tf_dataset() 方法来轻松地将数据集加载为 tf.data.Dataset,这样你就可以使用 Keras 的 compile 和 fit 方法马上开始训练。

  1. 使用 TFPreTrainedModel 或者 tf.keras.Model 来开始:
plain
>>> from transformers import TFAutoModelForSequenceClassification

>>> model = TFAutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased")
  1. 一个预处理类,比如分词器,特征提取器或者处理器:
plain
>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")
  1. 创建一个给数据集分词的函数
plain
>>> def tokenize_dataset(dataset):
...     return tokenizer(dataset["text"])
  1. 使用 map 将分词器应用到整个数据集,之后将数据集和分词器传给 prepare_tf_dataset()。如果你需要的话,也可以在这里改变批次大小和是否打乱数据集:
plain
>>> dataset = dataset.map(tokenize_dataset)  
>>> tf_dataset = model.prepare_tf_dataset(
...     dataset, batch_size=16, shuffle=True, tokenizer=tokenizer
... )
  1. 一切准备就绪后,调用 compile 和 fit 开始训练:
plain
>>> from tensorflow.keras.optimizers import Adam

>>> model.compile(optimizer=Adam(3e-5))
>>> model.fit(dataset)

Pipeline 任务 ​

使用 pipeline() 是利用预训练模型进行推理的最简单的方式。你能够将 pipeline() 开箱即用地用于跨不同模态的多种任务。来看看它支持的任务列表:

任务描述模态Pipeline
文本分类为给定的文本序列分配一个标签NLPpipeline(task=“sentiment-analysis”)
文本生成根据给定的提示生成文本NLPpipeline(task=“text-generation”)
命名实体识别为序列里的每个 token 分配一个标签(人, 组织, 地址等等)NLPpipeline(task=“ner”)
问答系统通过给定的上下文和问题, 在文本中提取答案NLPpipeline(task=“question-answering”)
掩盖填充预测出正确的在序列中被掩盖的 tokenNLPpipeline(task=“fill-mask”)
文本摘要为文本序列或文档生成总结NLPpipeline(task=“summarization”)
文本翻译将文本从一种语言翻译为另一种语言NLPpipeline(task=“translation”)
图像分类为图像分配一个标签Computer visionpipeline(task=“image-classification”)
图像分割为图像中每个独立的像素分配标签(支持语义、全景和实例分割)Computer visionpipeline(task=“image-segmentation”)
目标检测预测图像中目标对象的边界框和类别Computer visionpipeline(task=“object-detection”)
音频分类给音频文件分配一个标签Audiopipeline(task=“audio-classification”)
自动语音识别将音频文件中的语音提取为文本Audiopipeline(task=“automatic-speech-recognition”)
视觉问答给定一个图像和一个问题,正确地回答有关图像的问题Multimodalpipeline(task=“vqa”)

创建一个 pipeline() 实例并且指定你想要将它用于的任务,就可以开始了。你可以将 pipeline() 用于任何一个上面提到的任务,如果想知道支持的任务的完整列表,可以查阅 pipeline API 参考。不过, 在这篇教程中,你将把 pipeline() 用在一个情感分析示例上:

plain
>>> from transformers import pipeline

>>> classifier = pipeline("sentiment-analysis")

pipeline() 会下载并缓存一个用于情感分析的默认的预训练模型和分词器。现在你可以在目标文本上使用 classifier 了:

plain
>>> classifier("We are very happy to show you the 🤗 Transformers library.")
[{'label': 'POSITIVE', 'score': 0.9998}]

如果你有不止一个输入,可以把所有输入放入一个列表然后传给 pipeline(),它将会返回一个字典列表:

plain
>>> results = classifier(["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."])
>>> for result in results:
...     print(f"label: {result['label']}, with score: {round(result['score'], 4)}")
label: POSITIVE, with score: 0.9998
label: NEGATIVE, with score: 0.5309

pipeline() 也可以为任何你喜欢的任务遍历整个数据集。在下面这个示例中,让我们选择自动语音识别作为我们的任务:

plain
>>> import torch
>>> from transformers import pipeline

>>> speech_recognizer = pipeline("automatic-speech-recognition", model="facebook/wav2vec2-base-960h")

加载一个你想遍历的音频数据集(查阅 🤗 Datasets 快速开始 获得更多信息)。比如,加载 MInDS-14 数据集:

plain
>>> from datasets import load_dataset, Audio

>>> dataset = load_dataset("PolyAI/minds14", )

你需要确保数据集中的音频的采样率与 facebook/wav2vec2-base-960h 训练用到的音频的采样率一致:

plain
>>> dataset = dataset.cast_column("audio", Audio(sampling_rate=speech_recognizer.feature_extractor.sampling_rate))

当调用 "audio" 列时, 音频文件将会自动加载并重采样。 从前四个样本中提取原始波形数组,将它作为列表传给 pipeline:

plain
>>> result = speech_recognizer(dataset[:4]["audio"])
>>> print([d["text"] for d in result])
['I WOULD LIKE TO SET UP A JOINT ACCOUNT WITH MY PARTNER HOW DO I PROCEED WITH DOING THAT', "FODING HOW I'D SET UP A JOIN TO HET WITH MY WIFE AND WHERE THE AP MIGHT BE", "I I'D LIKE TOY SET UP A JOINT ACCOUNT WITH MY PARTNER I'M NOT SEEING THE OPTION TO DO IT ON THE AP SO I CALLED IN TO GET SOME HELP CAN I JUST DO IT OVER THE PHONE WITH YOU AND GIVE YOU THE INFORMATION OR SHOULD I DO IT IN THE AP AND I'M MISSING SOMETHING UQUETTE HAD PREFERRED TO JUST DO IT OVER THE PHONE OF POSSIBLE THINGS", 'HOW DO I THURN A JOIN A COUNT']

对于输入非常庞大的大型数据集(比如语音或视觉),你会想到使用一个生成器,而不是一个将所有输入都加载进内存的列表。查阅 pipeline API 参考 来获取更多信息。

在 pipeline 中使用另一个模型和分词器 ​

pipeline() 可以容纳 Hub 中的任何模型,这让 pipeline() 更容易适用于其他用例。比如,你想要一个能够处理法语文本的模型,就可以使用 Hub 上的标记来筛选出合适的模型。靠前的筛选结果会返回一个为情感分析微调的多语言的 BERT 模型,你可以将它用于法语文本:

plain
>>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment"

使用 AutoModelForSequenceClassification 和 AutoTokenizer 来加载预训练模型和它关联的分词器(更多信息可以参考下一节的 AutoClass):

plain
>>> from transformers import AutoTokenizer, AutoModelForSequenceClassification

>>> model = AutoModelForSequenceClassification.from_pretrained(model_name)
>>> tokenizer = AutoTokenizer.from_pretrained(model_name)

使用 TFAutoModelForSequenceClassification 和 AutoTokenizer 来加载预训练模型和它关联的分词器(更多信息可以参考下一节的 TFAutoClass):

plain
>>> from transformers import AutoTokenizer, TFAutoModelForSequenceClassification

>>> model = TFAutoModelForSequenceClassification.from_pretrained(model_name)
>>> tokenizer = AutoTokenizer.from_pretrained(model_name)

在 pipeline() 中指定模型和分词器,现在你就可以在法语文本上使用 classifier 了:

plain
>>> classifier = pipeline("sentiment-analysis", model=model, tokenizer=tokenizer)
>>> classifier("Nous sommes très heureux de vous présenter la bibliothèque 🤗 Transformers.")
[{'label': '5 stars', 'score': 0.7273}]

如果你没有找到适合你的模型,就需要在你的数据上微调一个预训练模型了。查看 微调教程 来学习怎样进行微调。最后,微调完模型后,考虑一下在 Hub 上与社区 分享 这个模型,把机器学习普及到每一个人! 🤗

AutoClass ​

在幕后,是由 AutoModelForSequenceClassification 和 AutoTokenizer 一起支持你在上面用到的 pipeline()。AutoClass 是一个能够通过预训练模型的名称或路径自动查找其架构的快捷方式。你只需要为你的任务选择合适的 AutoClass 和它关联的预处理类。

让我们回过头来看上一节的示例,看看怎样使用 AutoClass 来重现使用 pipeline() 的结果。

AutoTokenizer ​

分词器负责预处理文本,将文本转换为用于输入模型的数字数组。有多个用来管理分词过程的规则,包括如何拆分单词和在什么样的级别上拆分单词(在 分词器总结 学习更多关于分词的信息)。要记住最重要的是你需要实例化的分词器要与模型的名称相同, 来确保和模型训练时使用相同的分词规则。

使用 AutoTokenizer 加载一个分词器:

plain
>>> from transformers import AutoTokenizer

>>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
>>> tokenizer = AutoTokenizer.from_pretrained(model_name)

将文本传入分词器:

plain
>>> encoding = tokenizer("We are very happy to show you the 🤗 Transformers library.")
>>> print(encoding)
{'input_ids': [101, 11312, 10320, 12495, 19308, 10114, 11391, 10855, 10103, 100, 58263, 13299, 119, 102],
 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]}

分词器返回了含有如下内容的字典:

分词器也可以接受列表作为输入,并填充和截断文本,返回具有统一长度的批次:

plain
>>> pt_batch = tokenizer(
...     ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."],
...     padding=True,
...     truncation=True,
...     max_length=512,
...     return_tensors="pt",
... )
plain
>>> tf_batch = tokenizer(
...     ["We are very happy to show you the 🤗 Transformers library.", "We hope you don't hate it."],
...     padding=True,
...     truncation=True,
...     max_length=512,
...     return_tensors="tf",
... )

查阅预处理教程来获得有关分词的更详细的信息,以及如何使用 AutoFeatureExtractor 和 AutoProcessor 来处理图像,音频,还有多模式输入。

AutoModel ​

🤗 Transformers 提供了一种简单统一的方式来加载预训练的实例. 这表示你可以像加载 AutoTokenizer 一样加载 AutoModel。唯一不同的地方是为你的任务选择正确的AutoModel。对于文本(或序列)分类,你应该加载AutoModelForSequenceClassification:

plain
>>> from transformers import AutoModelForSequenceClassification

>>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
>>> pt_model = AutoModelForSequenceClassification.from_pretrained(model_name)

通过 任务摘要 查找 AutoModel 支持的任务.

现在可以把预处理好的输入批次直接送进模型。你只需要通过 ** 来解包字典:

plain
>>> pt_outputs = pt_model(**pt_batch)

模型在 logits 属性输出最终的激活结果. 在 logits 上应用 softmax 函数来查询概率:

plain
>>> from torch import nn

>>> pt_predictions = nn.functional.softmax(pt_outputs.logits, dim=-1)
>>> print(pt_predictions)
tensor([[0.0021, 0.0018, 0.0115, 0.2121, 0.7725],
        [0.2084, 0.1826, 0.1969, 0.1755, 0.2365]], grad_fn=<SoftmaxBackward0>)

🤗 Transformers 提供了一种简单统一的方式来加载预训练的实例。这表示你可以像加载 AutoTokenizer 一样加载 TFAutoModel。唯一不同的地方是为你的任务选择正确的 TFAutoModel,对于文本(或序列)分类,你应该加载 TFAutoModelForSequenceClassification:

plain
>>> from transformers import TFAutoModelForSequenceClassification

>>> model_name = "nlptown/bert-base-multilingual-uncased-sentiment"
>>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(model_name)

通过 任务摘要 查找 AutoModel 支持的任务.

现在通过直接将字典的键传给张量,将预处理的输入批次传给模型。

plain
>>> tf_outputs = tf_model(tf_batch)

模型在 logits 属性输出最终的激活结果。在 logits 上应用 softmax 函数来查询概率:

plain
>>> import tensorflow as tf

>>> tf_predictions = tf.nn.softmax(tf_outputs.logits, axis=-1)
>>> tf_predictions

所有 🤗 Transformers 模型(PyTorch 或 TensorFlow)在最终的激活函数(比如 softmax)之前 输出张量, 因为最终的激活函数常常与 loss 融合。模型的输出是特殊的数据类,所以它们的属性可以在 IDE 中被自动补全。模型的输出就像一个元组或字典(你可以通过整数、切片或字符串来索引它),在这种情况下,为 None 的属性会被忽略。

保存模型 ​

当你的模型微调完成,你就可以使用 PreTrainedModel.save_pretrained() 把它和它的分词器保存下来:

plain
>>> pt_save_directory = "./pt_save_pretrained"
>>> tokenizer.save_pretrained(pt_save_directory)
>>> pt_model.save_pretrained(pt_save_directory)

当你准备再次使用这个模型时,就可以使用 PreTrainedModel.from_pretrained() 加载它了:

plain
>>> pt_model = AutoModelForSequenceClassification.from_pretrained("./pt_save_pretrained")

当你的模型微调完成,你就可以使用 TFPreTrainedModel.save_pretrained() 把它和它的分词器保存下来:

plain
>>> tf_save_directory = "./tf_save_pretrained"
>>> tokenizer.save_pretrained(tf_save_directory)
>>> tf_model.save_pretrained(tf_save_directory)

当你准备再次使用这个模型时,就可以使用 TFPreTrainedModel.from_pretrained() 加载它了:

plain
>>> tf_model = TFAutoModelForSequenceClassification.from_pretrained("./tf_save_pretrained")

🤗 Transformers 有一个特别酷的功能,它能够保存一个模型,并且将它加载为 PyTorch 或 TensorFlow 模型。from_pt 或 from_tf 参数可以将模型从一个框架转换为另一个框架:

plain
>>> from transformers import AutoModel

>>> tokenizer = AutoTokenizer.from_pretrained(pt_save_directory)
>>> pt_model = AutoModelForSequenceClassification.from_pretrained(pt_save_directory, from_pt=True)
plain
>>> from transformers import TFAutoModel

>>> tokenizer = AutoTokenizer.from_pretrained(tf_save_directory)
>>> tf_model = TFAutoModelForSequenceClassification.from_pretrained(tf_save_directory, from_tf=True)

自定义模型构建 ​

你可以修改模型的配置类来改变模型的构建方式。配置指明了模型的属性,比如隐藏层或者注意力头的数量。当你从自定义的配置类初始化模型时,你就开始自定义模型构建了。模型属性是随机初始化的,你需要先训练模型,然后才能得到有意义的结果。

通过导入 AutoConfig 来开始,之后加载你想修改的预训练模型。在 AutoConfig.from_pretrained() 中,你能够指定想要修改的属性,比如注意力头的数量:

plain
>>> from transformers import AutoConfig

>>> my_config = AutoConfig.from_pretrained("distilbert/distilbert-base-uncased", n_heads=12)

使用 AutoModel.from_config() 根据你的自定义配置创建一个模型:

plain
>>> from transformers import AutoModel

>>> my_model = AutoModel.from_config(my_config)

使用 TFAutoModel.from_config() 根据你的自定义配置创建一个模型:

plain
>>> from transformers import TFAutoModel

>>> my_model = TFAutoModel.from_config(my_config)

查阅 创建一个自定义结构 指南获取更多关于构建自定义配置的信息。

Trainer - PyTorch 优化训练循环 ​

所有的模型都是标准的 torch.nn.Module,所以你可以在任何典型的训练模型中使用它们。当你编写自己的训练循环时,🤗 Transformers 为 PyTorch 提供了一个 Trainer 类,它包含了基础的训练循环并且为诸如分布式训练,混合精度等特性增加了额外的功能。

取决于你的任务, 你通常可以传递以下的参数给 Trainer:

  1. PreTrainedModel 或者 torch.nn.Module:
plain
>>> from transformers import AutoModelForSequenceClassification

>>> model = AutoModelForSequenceClassification.from_pretrained("distilbert/distilbert-base-uncased")
  1. TrainingArguments 含有你可以修改的模型超参数,比如学习率,批次大小和训练时的迭代次数。如果你没有指定训练参数,那么它会使用默认值:
plain
>>> from transformers import TrainingArguments

>>> training_args = TrainingArguments(
...     output_dir="path/to/save/folder/",
...     learning_rate=2e-5,
...     per_device_train_batch_size=8,
...     per_device_eval_batch_size=8,
...     num_train_epochs=2,
... )
  1. 一个预处理类,比如分词器,特征提取器或者处理器:
plain
>>> from transformers import AutoTokenizer

>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")
  1. 加载一个数据集:
plain
>>> from datasets import load_dataset

>>> dataset = load_dataset("rotten_tomatoes")
  1. 创建一个给数据集分词的函数,并且使用 map 应用到整个数据集:
plain
>>> def tokenize_dataset(dataset):
...     return tokenizer(dataset["text"])

>>> dataset = dataset.map(tokenize_dataset, batched=True)
  1. 用来从数据集中创建批次的 DataCollatorWithPadding:
plain
>>> from transformers import DataCollatorWithPadding

>>> data_collator = DataCollatorWithPadding(tokenizer=tokenizer)

现在把所有的类传给 Trainer:

plain
>>> from transformers import Trainer

>>> trainer = Trainer(
...     model=model,
...     args=training_args,
...     train_dataset=dataset["train"],
...     eval_dataset=dataset["test"],
...     processing_class=tokenizer,
...     data_collator=data_collator,
... )

一切准备就绪后,调用 train() 进行训练:

对于像翻译或摘要这些使用序列到序列模型的任务,用 Seq2SeqTrainer 和 Seq2SeqTrainingArguments 来替代。

你可以通过子类化 Trainer 中的方法来自定义训练循环。这样你就可以自定义像损失函数,优化器和调度器这样的特性。查阅 Trainer 参考手册了解哪些方法能够被子类化。

另一个自定义训练循环的方式是通过回调。你可以使用回调来与其他库集成,查看训练循环来报告进度或提前结束训练。回调不会修改训练循环。如果想自定义损失函数等,就需要子类化 Trainer 了。

​