R-Adapter:零样本模型微调新突破,提升鲁棒性与泛化能力 | ECCV 2024

news/2024/11/15 9:51:08/文章来源:https://www.cnblogs.com/VincentLee/p/18399986

大规模图像-文本预训练模型实现了零样本分类,并在不同数据分布下提供了一致的准确性。然而,这些模型在下游任务中通常需要微调优化,这会降低对于超出分布范围的数据的泛化能力,并需要大量的计算资源。论文提出新颖的Robust AdapterR-Adapter),可以在微调零样本模型用于下游任务的同时解决这两个问题。该方法将轻量级模块集成到预训练模型中,并采用新颖的自我集成技术以提高超出分布范围的鲁棒性,并大幅减少存储开销。此外,论文提出了针对视觉-语言下游任务设计的MPM-NCE损失,确保多个图像-文本对的精确对齐和具有区分性的特征学习。

来源:晓飞的算法工程笔记 公众号

论文: Efficient and Versatile Robust Fine-Tuning of Zero-shot Models

  • 论文地址:https://www.arxiv.org/abs/2408.05749
  • 论文代码:http://cvlab.postech.ac.kr/research/R-Adapter

Introduction


  大规模联合图像和文本数据预训练模型的出现在计算机视觉领域引起了范式转变。通过对大量图像-文本对的嵌入进行对齐,这些模型实现了零样本推断,并展现出在不同数据分布下广泛泛化的显著能力。尽管它们在零样本情境下表现出色,但它们无法与监督学习模型相媲美,需要进行微调以发挥其全部能力。然而,传统的全面微调会产生两个主要挑战:1)全面微调损害了模型对于超出分布范围(OOD)数据的泛化能力,而这对于数据变异性不可预测的实际应用至关重要。2)它需要大量的计算资源、内存和存储,而随着大规模预训练模型的不断增大,这是不切实际的。

  最近,针对这些挑战提出了几种微调方法。鲁棒微调的目标是在微调零样本模型的同时保持对OOD的鲁棒性,而参数高效微调(PEFT)仅更新一小部分参数,同时保持预训练参数的冻结状态。然而,每种方法只解决其中一个挑战,同时在另一个挑战上仍然存在不足。如图1所示,现有的鲁棒微调方法仍然需要微调整个模型,导致训练代价高昂。此外,它们仅针对分类任务,因此通常仅训练图像编码器,从模型中排除了零样本推断能力。另一方面,与鲁棒微调相比,PEFT在分布偏移下的性能显著滞后。它们的关键缺点凸显了需要新的微调方法,同时解决鲁棒微调和PEFT分别应对的两个挑战。

  本文提出了一种名为鲁棒适配器(R-Adapter)的新型微调方法,旨在提高PEFT的鲁棒性,并增强鲁棒微调的效率。在适配器微调方法的基础上向预训练模型添加额外的轻量级模块,R-Adapter引入了新颖的自我集成策略,以增强OOD的鲁棒性。

  受到在权重空间中平均多个模型时观察到的鲁棒性增益的启发,通过一种独特的方式在单个模型内实现这种策略。这种方法在任务特定性能和针对分布偏移的鲁棒性之间取得了良好的平衡,同时显著降低了存储成本。具体而言,R-Adapter通过三种自我集成技术实现这一目标。它随机丢弃适配器模块,从而动态生成并集成不同子网络,以各种配置组合适配器和预训练层。此外,累积适配器权重以形成一个时间集成,捕捉整个学习过程中产生的所有模型。此外,通过重新缩放适配器的权重,并通过重新参数化将其整合到预训练层中,论文实现了在没有两个单独模型的情况下,在预训练和微调模型的权重之间实现无缝的线性插值。

  此外,论文提出了一种名为Multi-Positive Margin NCEMPM-NCE)损失函数,专为在视觉-语言下游任务上进行有效微调而设计。这些任务通常涉及复杂的关系,其中多个图像可以对应于相同的文本,反之亦然。与传统的对比损失(例如InfoNCE)不同,后者接受单一正样本对,并因此经常导致这些关系中的语义不匹配,MPM-NCE考虑了多个正样本对,从而更精确地对齐跨各种图像和文本对。此外,MPM-NCE引入了一个角度边距以惩罚负样本对,使模型能够学习对下游任务至关重要的高度区分的特征。因此,所提出的损失函数显著改善了任务特定性能,在IDOOD环境下都带来了益处。

  论文的方法在微调后实现了零样本推理,在图像分类任务之外扩展了其适用性范围,适用于广泛的应用领域。为了展示其多功能性,论文提出了一个新的用于鲁棒微调的评估基准,包括五个任务:三种情景下的图像分类任务、跨模态检索和开放词汇分割。大量实验证明,与现有的鲁棒微调和PEFT方法相比,论文的方法在分布转移条件下表现出卓越性能,同时使用的参数更少。

  本文的主要贡献有四点:

  1. 提出了一个高效且多功能的鲁棒微调框架,融合了PEFT和鲁棒微调的优势,这是第一个兼具两者优势的方法。

  2. 提出了R-Adapter,采用自集成技术,借助单个带有适配器的模型实现权重空间集成。能够在减少存储成本的同时增强鲁棒性,因为不需要多个模型。

  3. 开发了适用于微调的MPM-NCE损失,利用多个正样本对和引入角度间隔,确保了多个图像-文本对的精确对齐和具有区分性的特征学习。

  4. 首次将鲁棒微调的基准拓展到图像分类之外的任务,包括跨模态检索和开放词汇分割,从而允许评估其广泛适用性。论文的方法在各种任务中取得了最先进的性能,仅微调了13%CLIP编码器参数。

Proposed Method


Preliminary

  • CLIP Encoders

CLIP由两个编码器组成,分别用于从图像和文本中提取特征。每个编码器由一系列Transformer层组成,每个层包括多头注意力(MHA)、层归一化(LN)和前馈神经网络(FFN)。具体而言,第 \(l\)Transformer层的公式如下:

\[\begin{equation} \begin{aligned} \bar{X_l} &= \textrm{MHA}(\textrm{LN}(X_{l-1})) + X_{l-1}, \\ X_l &= \textrm{FFN}(\textrm{LN}(\bar{X_l})) + \bar{X_l}. \label{eq:Transformer_layer} \end{aligned} \end{equation} \]

MHA包括对查询、键和值进行 \(k\) 头自注意力操作,通过对输入进行独立的线性投影来实现,其公式为:

\[\begin{equation} \begin{aligned} \textrm{MHA}(X) &= [\textrm{Attn}^1(X), ..., \textrm{Attn}^k(X)]W_O,\\ \textrm{Attn}^i(X) &= \textrm{softmax}\big((XW_{Q}^{i})(XW_{K}^{i})^{\top}/{\sqrt{d_h}} \big)(XW_{V}^{i}), \label{eq:MHA} \end{aligned} \end{equation} \]

  其中 \([\cdot,\cdot]\) 表示拼接, \(d_h\) 设为 \(d/k\)\(W_{Q}^{i}\in\mathbb{R}^{d\times d_h}\)\(W_{K}^{i}\in\mathbb{R}^{d\times d_h}\)\(W_{V}^{i}\in\mathbb{R}^{d\times d_h}\)\(W_{O}\in\mathbb{R}^{d\times d}\) 是线性投影矩阵。FFN由两个线性层和一个非线性层组成:

\[\begin{equation} \textrm{FFN}(X) = \sigma(XW_1+b_1)W_2 + b_2, \label{eq:FFN} \end{equation} \]

  其中 \(W_1\in\mathbb{R}^{d\times4d}\) , \(W_2\in\mathbb{R}^{4d\times d}\) , \(b_1 \in \mathbb{R}^{4d}\) , 和 \(b_2 \in \mathbb{R}^d\) 分别是线性投影的权重和偏置; \(\sigma(\cdot)\) 表示GELU函数。

  • Contrastive Learning

CLIP编码器被训练用于预测哪些文本描述与给定的一组图像匹配,反之亦然。这通过使用InfoNCE损失来进行对比学习来实现,该损失迫使图像嵌入和其对应的文本嵌入彼此靠近,并远离批次中的其他文本嵌入。设 \(f(\cdot)\)\(g(\cdot)\) 分别是图像和文本的CLIP编码器。给定一个批次包含 \(B\) 个图像-文本对 \(\mathcal{B} =\big\{(I_1,T_1), ..., (I_B,T_B)\big\}\) ,损失函数定义为:

\[\begin{equation} \begin{aligned} \mathcal{L}(\mathcal{B}) = &-\sum_{i=1}^{B}\Bigg(\log\frac{e^{f_i \cdot g_i/\tau }}{\sum_{j=1}^{B}e^{f_i \cdot g_j/\tau }} +\log\frac{e^{f_i\cdot g_i/\tau }}{\sum_{j=1}^{B}e^{f_j\cdot g_i/\tau}}\Bigg), \label{eq:InfoNCE_Loss} \end{aligned} \end{equation} \]

  其中 \(f_i = \frac{f(I_i)}{||f(I_i)||_2}\) , \(g_i = \frac{g(T_i)}{||g(T_i)||_2}\)\(\tau\) 表示一个可学习的温度参数。

Problem Setup

  论文的目标是在保留其固有的离群分布泛化能力的同时,高效地对视觉-语言预训练模型进行各种下游任务的微调。虽然大多数现有的鲁棒微调方法局限于分类任务,但论文将范围扩大到为各种下游任务,如图像分类、跨模态检索和开放词汇分割等,提供鲁棒微调模型。

  给定一个图像-文本预训练模型,目标是使用一个面向目标下游任务的内分布(ID)训练数据集 \(\mathcal{D}_{\mathcal{I}}=\{(I_i, T_i)\}_{i=1}^{n}\) 对其进行适应,其中 \(I\) 表示一个图像, \(T\) 是对应于该图像的文本描述。同时,旨在提高模型在一个离群分布(OOD)测试数据集 \(\mathcal{D}_{\mathcal{O}}=\{(I_j, T_j)\}_{j=1}^{m}\) 上的性能。内分布和离群分布数据集 \(\mathcal{D}_{\mathcal{I}}\)\(\mathcal{D}_{\mathcal{O}}\) 分别从不同概率分布 \(p_{\mathcal{I}}(I,T)\)\(p_{\mathcal{O}}(I,T)\) 中采样,当 \(p_{\mathcal{I}}(I,T)\neq p_{\mathcal{O}}(I,T)\) 时即为表现出分布转移。在分类任务中, \(T\) 表示目标类的文本描述,通过从一组预定义模板中进行采样构建(例如,“一张{class}的照片”)。对于其他视觉-语言任务, \(T\) 可能是与图像 \(I\) 相关联的标题之一。

Robust Adapter (R-Adapter)

  为了实现高效且鲁棒的微调,论文引入了基于PEFT框架的R-AdapterPEFT框架在微调少量附加的可学习参数的同时冻结预训练模型,但在训练中对该框架的朴素应用可能会导致对内分布数据的显著偏向(参见表2)。受到集成增强在各种分布下的泛化能力的启发,R-Adapter设计了三种新颖的自集成策略,以实现鲁棒微调而不在训练和推理期间增加计算负载。

  • Design of R-Adapter

R-Adapter建立在适配器微调框架之上,在该框架中向预训练模型添加了轻量级模块。具体而言,R-Adapter中的适配器模块采用了Houlsby适配器的简化版本,去除了非线性层和偏置。该模块被构建为一个残差块,由以下权重矩阵组成:

\[\begin{equation} h(X) = XW_{\textrm{adp}} + X, \label{eq:Adapter} \end{equation} \]

  其中, \(X\) 表示预训练块的输出, \(W_{\textrm{adp}} \in \mathbb{R}^{d\times d}\) 是论文适配器的权重矩阵。对于全样本学习,保持 \(W_{\textrm{adp}}\) 的满秩结构以保留足够的容量。在少样本学习中,可以通过将 \(W_{\textrm{adp}}\) 分解为低秩矩阵 \(BA\) 的乘积来采用瓶颈结构,其中 \(B\in \mathbb{R}^{d\times r}\)\(A\in \mathbb{R}^{r\times d}\) ,且秩 \(r \ll d\) 。这种分解避免了过参数化,并显著减少了参数数目和计算量。

  在图像和文本编码器的每个Transformer层中部署适配器,放置在MHAMulti-Head Attention)和FFNFeed-Forward Network)层之后,如图2所示。

  由于适配器之前没有非线性结构,可以通过将其与最接近的预训练层集成进行重参数化,从而在推理过程中消除适配器的额外计算开销。用 \(W_{\textrm{org}}\) 表示适配器之前的预训练层的权重,可以是来自MHA\(W_O\) 或者FFN中的 \(W_2\) ,相应的偏置 \(b_{\textrm{org}}\)FFN中的 \(b_2\) 。给定预训练层的输入 \(X_{\textrm{in}}\) ,那么重新参数化的过程如下进行:

\[\begin{align} \begin{aligned} h(X_\textrm{in}W_\textrm{org} + b_\textrm{org}) &= X_\textrm{in}W_\textrm{org}(W_{\textrm{adp}} + \mathrm{I}) + b_{\textrm{org}}W_{\textrm{adp}} + b_{\textrm{org}} \\ &= X_\textrm{in}W_\textrm{rep} + b_\textrm{rep}, \label{eq:rep} \end{aligned} \end{align} \]

  其中, \(\mathrm{I}\in\mathbb{R}^{d\times d}\) 是单位矩阵, \(W_\textrm{rep} = W_\textrm{org}(W_\textrm{adp}+\mathrm{I})\)\(b_\textrm{rep} = b_\textrm{org}(W_\textrm{adp}+\mathrm{I})\)

  • Dynamic Ensemble by Adapter Dropping

  为了增强R-AdapterOOD鲁棒性,加入适配器丢弃的动态集成技术。在训练过程中,适配器模块以以下方式被随机停用:

\[\begin{equation} h(X) = \frac{\gamma}{1-p} \cdot XW_{\textrm{adp}} + X, \label{eq:Stochastic} \end{equation} \]

  其中, \(\gamma\) 是从 \(\textrm{Bernoulli}(1-p)\) 中抽取的独立变量, \(p\) 是适配器丢弃的概率。

  与用于特征稀疏性的dropout或用于模型深度减少的drop-path不同,该技术独特地专注于在保持预训练特征的同时随机禁用适配器层。适配器丢弃不适用于推理阶段,这样可以创建一个由预训练层和适配器层组合而成的子网络集合。这种策略能够同时保留预训练知识和微调知识的动态集成多模型,从而在IDOOD数据上提升性能。

  • Temporal Ensemble by Accumulation

  通过利用适配器权重的历史累积,引入一个时间集成策略来提高模型的鲁棒性。在训练过程中,通过对多次迭代中的权重进行平均,集成技术捕捉到对特征空间的更广泛了解。累积适配器的权重 \(\tilde{W}_\textrm{adp}\) 则通过指数移动平均进行更新:

\[\begin{equation} \tilde{W}_\textrm{adp} \leftarrow m \cdot \tilde{W}_\textrm{adp} + (1-m) \cdot {W}_\textrm{adp}, \label{eq:Accumulation} \end{equation} \]

  其中, \(m \in [0, 1]\) 是控制动量更新速率的系数。这种方法在内存使用方面非常高效,因为只有适配器的参数进行了动量更新,而不是整个模型的参数。在推理阶段,利用累积的权重 \(\tilde{W}_\textrm{adp}\) 来计算重参数化权重 \(\tilde{W}_\textrm{rep}\) 和偏置 \(\tilde{b}_\textrm{rep}\)

  • Weight-space Ensemble by Re-scaling

  最后,引入一种通过重新调整参数实现预训练层和微调层之间的权重空间集成的策略。传统的权重空间集成(WiSE-FT)在原始预训练参数和微调参数之间进行线性插值,因此需要存储两个独立的模型。相比之下,论文采用重参数化的权重 \(\tilde{W}_\textrm{rep}\) 作为微调层的权重,从而进化了这个概念。我们在推理时重新调整适配器的权重并对其重参数化,将权重空间集成简化为单一模型内的实现。该过程可以表达如下:

\[\begin{align} \begin{aligned} \underbrace{\alpha \tilde{W}_\textrm{rep} + (1-\alpha) W_\textrm{org}}_\texttt{{{{Weight-space Ensemble}}}} &= \alpha W_\textrm{org}\tilde{W}_\textrm{adp} + \alpha W_\textrm{org} + (1-\alpha) W_\textrm{org} \\[-17pt] &= \underbrace{W_\textrm{org}(\overbrace{\alpha \tilde{W}_\textrm{adp}}^\texttt{{{{Re-scaling}}}} \;+\; \mathrm{I}) = W_\textrm{ens}}_\texttt{{{Re-parametrization}}}, \\ \label{eq:rescale} \end{aligned} \end{align} \]

  这里, \(W_\textrm{ens}\) 表示集成的权重, \(\alpha\) 是一个重调整系数。系数 \(\alpha\) 充当插值因子,调整原始预训练权重 \(W_\textrm{org}\) 与微调层调整权重之间的平衡。这种技术不仅可以提高在分布转移下的准确性,也能在ID数据上保持高性能。关键是,与WiSE-FT不同,该方法不需要在存储中维护两个单独的完整模型,因此更有效地促进了更节省存储空间的权重空间集成。

MPM-NCE Loss for Downstream Task

  为了增强下游任务的学习能力,使用与任务特征密切对齐的损失函数至关重要。视觉-语言任务通常涉及多个模态之间的对应关系。例如,在分类任务中,对同一类别使用不同的文本模板可能导致多个文本描述与单个图像匹配,反之亦然。这种情况在涉及图像和标题的跨模态检索任务中也会发生。当将零样本模型调整到新任务时,一种常见方法是使用预训练中使用的InfoNCE损失。然而,对于存在多个正样本的任务,该损失并不理想,因为它只考虑了单个正样本对。此外,InfoNCE学习了正负样本之间的顺序,这可能不会为下游任务产生足够有区分力的特征。

  为了解决这些限制,论文提出了MPM-NCE损失,旨在适应这些任务的多正样本性质,同时增强所学嵌入的区分能力。这个损失函数有两个关键改进。首先,使用软标签为多个正样本对分配相等的概率,公式如下:

\[\begin{equation} \tilde{y}_{ij} = \frac{(1-\epsilon)\cdot y_{ij}}{|P(i)|} + \frac{\epsilon \cdot (1-y_{ij})}{B-|P(i)|} \in [0,1], \label{eq:soft_label} \end{equation} \]

  其中 \(y_{ij} \in \{0,1\}\) 表示样本 \(i\)\(j\) 之间的正关系, \(P(i)\) 是包括自身在内的样本 \(i\) 的正样本集合, \(\epsilon\) 是一种平滑标签噪声。这种软标签确保在下游任务中正确对齐多个图像-文本对。此外,软标签还可以包含 \(\epsilon\) ,通过对标签引入小的扰动来降低过拟合风险。

  第二个改进是对负样本对应用边界 \(\delta\) 。这个边界通过确保负样本对不仅是不同的,而且还要被一定的阈值分开,增强了所学特征的区分度。融合了这些改进,MPM-NCE公式如下:

\[\begin{equation} \mathcal{L}(\mathcal{B}) = -\sum_{i,j=1}^{B}\Bigg(\tilde{y}_{ij}\log\frac{e^{(f_i \cdot g_j+\delta_{ij})/\tau }}{\sum_{k=1}^{B}e^{(f_i \cdot g_k + \delta_{ik})/\tau}} +\tilde{y}_{ji}\log\frac{e^{ (f_j \cdot g_i+\delta_{ji})/\tau}}{\sum_{k=1}^{B}e^{(f_k \cdot g_i + \delta_{ki})/\tau}}\Bigg), \label{eq:MPM_NCE} \end{equation} \]

  其中温度 \(\tau\) 被设为常数值0.01\(\delta_{ij}\) 对于正关系为0,对于其他情况为 \(\delta\) 。因此,MPM-NCE损失鼓励模型正确对齐多个图像-文本对,并学习具有区分度的特征,从而在IDOOD下显著提高性能。

Experiments




如果本文对你有帮助,麻烦点个赞或在看呗~
更多内容请关注 微信公众号【晓飞的算法工程笔记】

work-life balance.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/793005.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kubernetes-etcd备份恢复

目录使用etcdctl备份与恢复简介集群信息etcdctl安装下载安装同步到其他节点配置环境变量查看集群状态查看所有key查看指定key备份所有节点创建备份目录备份etcd数据恢复删除资源所有master节点停止etcd所有master节点备份原有数据master01恢复master02恢复master03恢复所有节点…

使用 Android Lua Helper 在VSCODE中调试安卓Lua应用

一、VSCODE 与 Android Lua Helper 的功能特点 Visual Studio Code(VSCODE)是一款功能强大的代码编辑器,它以其高度可定制的界面、强大的扩展生态系统、流畅的性能表现以及对众多编程语言的天然支持而备受开发者青睐。在众多的开发场景中,VSCODE 都展现出了卓越的性能和灵活…

【git】No user exists for uid 1000 fatal: 无法读取远程仓库。

一、问题今天拉取代码时,突然报错 二、处理过程 1、检查用户信息 $ id -u1000用户的id是对的 那是因为什么呢2、重启终端 发现还是不行3、重启电脑 发现还是不行三、解决方案 最终重新生效环境变量 $ source ~/.bashrc然后重新执行拉取更新 $ git fetchremote: Enumerating ob…

最罕见的性格,在程序员里却最常见?它就是。。

当然,性格测试也不绝对准确,毕竟谁还没有一点儿 “逆反” 心理呢?大家好,我是程序员鱼皮。不知道大家有没有了解过 MBTI?这是目前特别流行的人格测试,可以帮助你更了解自己。 MBTI 将人格分为 4 个维度,每个维度有 2 个选项:比如在精力来源这点,就分为内倾和外倾(俗称…

etcd集群新增节点和移除节点

etcd集群新增节点和删除节点 现在的集群信息是: 新增节点1、下载etcd二进制包wget https://github.com/etcd-io/etcd/releases/download/v3.5.15/etcd-v3.5.15-linux-amd64.tar.gz2、创建etcd目录mkdir -p /data/etcd/{data,ssl,bin}3、解压并移动etcd命令至etcd目录tar zxf …

My SQL 列转行操作

原表结构如下,我们可以发现,“日运输量”和“车次”是在同一张表中相互独立的两个字段,即独立的两列数据,下面,我将系统中的测试数据以及代码全部放出来,以解释列转行的操作方法 原表数据库查询代码:1 SELECT 2 yzrq AS 运作日期, 3 DATE_FORMAT( yzrq, %Y-%m )…

VS中 调试逐语句和逐过程的区别

逐过程(F10)在遇到函数时,会把函数从整体上看做一条语句,不会进入函数内部;逐语句(F11)在遇到函数时,认为函数由多条语句构成,会进入函数内部。

使用 nuxi init 创建全新 Nuxt 项目

title: 使用 nuxi init 创建全新 Nuxt 项目 date: 2024/9/6 updated: 2024/9/6 author: cmdragon excerpt: 摘要:本文介绍了如何使用nuxi init命令创建全新的Nuxt.js项目,包括安装所需环境、命令使用方法、指定模板、强制克隆、启动开发服务器等步骤,并提供了完整的项目初…

KUnit:设备模拟重定向

设备模拟 有些驱动文件是需要device的,所以KUnit提供了一些设备模拟的方法,并且还提供了总线来管理设备的生命周期。 下面先以clock device模拟举例(drivers/clk/clk_test.c)首先用一个struct来模拟这个clk设备。其中clk_hw是clk的描述,rate相当于模拟设备的波特率寄存器s…

IDA 动态调试初步学习

题目 https://files.buuoj.cn/files/985826f5dda0d8665ed997a49321dd88/attachment.zip 1C这个值太小导致加密失败,所以考虑动态调试修改1C为更大的值选择调试F2下一些断点找到1C在内存中的位置F9开始调试先F7单步,观察右下角的Stack view,内存中出现1C先选中,然后按F2,然后修改…

JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆对象的区别

JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆对象的区别JavaScript 中 structuredClone 和 JSON.parse(JSON.stringify()) 克隆对象的异同点 一、什么是 structuredClone? 1. structuredClone 的发展 structuredClone 是在 ECMAScript 2021(ES12)标…

【c】printf()中%占位符的选取和使用: %d, %s等

格式占位符速通 格式占位符 %格式占位符 % 是在 C/C++ 语言中格式输入函数,如 scanf、printf 等函数中使用。 其意义就是起到格式占位的意思,表示在该位置有输入或者输出。规定符%d 十进制有符号整数 %u 十进制无符号整数 %f 浮点数 %s 字符串 %c 单个字符 %p 指针的值 %e 指…