1. 从玩具到产线:工业级人脸识别到底难在哪
很多人跟着教程跑完一个卷积神经网络的人脸分类 Demo,看着验证集准确率冲到 98%,就觉得自己已经摸到了人脸识别的门槛。但真要把这套东西放到一个每天要处理几万张抓拍图、几十路视频流、还要保证误识率低于万分之一的生产环境里,你会发现之前那套玩具代码几乎每一行都得推倒重来。我自己第一次做工业级人脸识别项目的时候,踩的坑比写的代码还多,模型在测试集上表现很好,一上线就各种翻车,光照一变、角度一偏、口罩一戴,识别率断崖式下跌。
这篇文章要聊的,就是怎么从一个只会跑 MNIST 和 CIFAR 的小白,一步步搭出一套真正能扛住工业生产环境的人脸识别系统。核心关键词包括CNN 卷积神经网络、人脸检测、人脸对齐、特征提取、向量检索、模型量化、推理加速。整套系统解决的核心问题是:在复杂光照、多角度、多姿态、遮挡等真实场景下,稳定地完成人脸检测、特征比对和身份识别,并且把误识率和漏识率控制在一个可接受的工程范围内。
适合谁来读?如果你已经能看懂卷积、池化、全连接这些基础概念,跑通过至少一个图像分类项目,但对“怎么把模型变成产品”完全没有概念,那这篇内容就是为你准备的。我不会堆砌公式,而是把每个环节为什么这么做、参数怎么定、坑在哪里,用从业者的视角掰开揉碎讲清楚。整套流程我会拆成数据、检测、对齐、特征、检索、部署六大块,每一块都给出可复现的操作路径和实测经验。
先说一个最容易被忽视的认知:工业级人脸识别不是“一个模型”的事,而是一条流水线。检测负责找到人脸在哪,对齐负责把人脸摆正,特征提取负责把一张脸变成一串数字向量,检索负责在几百万甚至上千万条向量里找到最像的那一个。任何一环掉链子,整条流水线的效果都会崩。很多新手一上来就死磕特征模型,结果检测框歪了、对齐没做,特征再好也白搭。所以接下来的内容,我会按照这条流水线的顺序,一块一块往下拆。
2. 数据准备:决定上限的不是模型而是数据
2.1 工业场景下的数据长什么样
学术数据集里的人脸大多是正脸、光照均匀、背景干净,但工业生产环境完全不是这样。我经手过的一个项目,摄像头装在通道上方,人来人往,有低头看手机的、有侧脸走过的、有戴帽子戴口罩的,还有逆光和大中午顶光的情况。这种数据你拿公开数据集直接训练,模型根本没见过,上线必崩。所以数据准备的第一步,是搞清楚你的真实场景里人脸到底长什么样。
我的做法是先采集一批现场抓拍图,不用多,几千张就够,然后人工过一遍,把问题归类。常见的几类问题包括:光照极端(过曝、欠曝、逆光)、姿态偏转(侧脸超过 45 度)、遮挡(口罩、墨镜、刘海)、运动模糊、分辨率过低。每一类问题你都要评估它在实际业务里占多大比例,因为不同问题对后续环节的影响完全不同。比如侧脸超过 60 度的人脸,检测都很难框准,更别说特征比对了,这种样本要么在业务上规避,要么在数据里专门补足。
提示:不要一上来就想着用海量数据堆模型。先把现场数据的分布摸清楚,比盲目扩充数据量重要十倍。我见过太多团队花几个月标注了几十万张图,结果分布和真实场景对不上,白干。
2.2 数据清洗与标注的实操要点
数据清洗这块,我总结了一个“三看”原则:看清晰度、看角度、看遮挡。清晰度低于一定阈值的直接剔除,因为模糊人脸对特征提取是负贡献;角度超过业务容忍范围的剔除或单独归类;遮挡严重的根据业务需求决定是否保留。这里有个经验值,人脸区域的像素宽度低于 80px 的,特征质量会明显下降,低于 40px 的基本没法用,这个阈值可以根据你的模型输入尺寸反推。
标注环节,工业级项目一般需要两类标注:人脸框和关键点。人脸框用于训练检测模型,关键点(通常是 5 点:左右眼、鼻尖、左右嘴角)用于对齐。标注工具市面上有不少开源的,选一个支持快捷键、支持多人协作的就行。标注质量的控制很关键,我的做法是抽 10% 做交叉复核,两个人标同一张图,框的 IoU 低于 0.85 的就打回重标。别小看这一步,标注噪声会直接传导到模型,尤其是关键点,偏几个像素对齐就会歪。
数据增强这块,工业场景我强烈建议做这几类:随机亮度对比度调整、随机高斯噪声、随机运动模糊、随机遮挡(模拟口罩墨镜)。注意,水平翻转要慎用,因为人脸本身接近左右对称,翻转带来的增益有限,反而可能引入关键点标注的左右混淆。旋转增强的角度范围要结合你的业务,一般正负 15 度以内比较安全,超过这个范围对齐环节会很难处理。
2.3 数据配比与难例挖掘
数据配比是个容易被忽略但极其重要的点。假设你的业务里 90% 是正脸,10% 是侧脸,那训练集里侧脸的比例就不能只有 1%,否则模型对侧脸的学习严重不足。我的经验是把难例(侧脸、遮挡、暗光)的比例适当上采样,让它们占到总数据的 20% 到 30%,这样模型才会在这些场景上花更多“注意力”。当然也不能过度,否则正脸的精度会掉。
难例挖掘是个持续的过程。系统上线后,把识别置信度低或者比对失败的样本回流回来,人工确认后加入训练集,迭代几轮之后模型在真实场景的表现会明显提升。这个闭环机制是工业级系统和玩具 Demo 最大的区别之一。我一般会设一个阈值,比如比对相似度低于 0.6 的样本自动进入待审核队列,每周处理一次,把确认的难例补充进下一版训练数据。
3. 人脸检测:整条流水线的第一道关卡
3.1 为什么检测比识别更值得投入
很多人把精力全砸在特征模型上,觉得识别准不准全看特征提取。但实际经验告诉我,检测才是整条流水线的地基。检测框偏了,对齐就会歪,对齐歪了,特征提取出来的向量就是错的,后面检索再牛也救不回来。我做过一个对比实验,同一个特征模型,检测框 IoU 从 0.9 降到 0.7,识别准确率直接掉了十几个百分点。所以检测这一环,值得你花大力气。
工业场景下的检测难点主要有几个:小脸检测(远处的人脸可能只有几十像素)、密集人脸(通道里人挤人)、极端光照、遮挡。针对这些难点,选型上我一般推荐两类方案:一类是经典的单阶段检测器,速度快、部署简单;另一类是带关键点回归的检测器,一次前向就能同时输出框和关键点,省去单独的关键点模型。后者在工业级项目里更实用,因为流水线越短,延迟和故障点越少。
3.2 检测模型的训练细节与参数选择
训练检测模型,输入分辨率是个关键参数。分辨率太低,小脸检测不到;分辨率太高,推理速度扛不住。我的经验是,如果业务场景里最小人脸宽度在 40px 左右,输入分辨率设到 640 基本够用;如果小脸更多,可以上到 800 甚至 1024,但要配合推理加速手段。这里有个计算公式可以参考:输入分辨率 ≈ 最小人脸宽度 × 16。比如最小人脸 40px,40×16=640,这个经验公式在多数场景下比较靠谱。
锚框(anchor)的设置也很讲究。工业场景人脸尺度跨度大,从几十像素到几百像素都有,所以锚框的尺度要覆盖得足够宽。我一般会统计训练集里人脸框的宽高分布,然后按聚类的方式确定锚框尺寸,而不是拍脑袋设。聚类用 k-means 就行,把所有人脸框的宽高做聚类,取 5 到 9 个聚类中心作为锚框。这样设出来的锚框和你的数据分布匹配,召回率会明显提升。
正负样本的划分策略直接影响训练效果。IoU 大于 0.5 的算正样本,小于 0.3 的算负样本,中间的不参与损失计算,这是比较通用的做法。但工业场景里小脸多,小脸的正样本本来就少,所以对小脸的 IoU 阈值可以适当放宽,比如 0.4 就算正样本,避免小脸因为匹配不上而学不到。这个细节很多教程不会讲,但实测下来对小脸召回帮助很大。
3.3 检测后处理:NMS 与置信度阈值
检测模型输出的是一堆候选框,后处理的核心是 NMS(非极大值抑制)和置信度过滤。NMS 的 IoU 阈值一般设 0.4 到 0.5,设太高会保留大量重叠框,设太低会把挨得近的两张脸误删。密集人脸场景下,我建议用 Soft-NMS 或者类似的改进方案,避免把相邻人脸框误抑制掉。置信度阈值要根据业务调,宁可漏检不可误检的场景(比如门禁),阈值设高一点,比如 0.7;宁可误检不可漏检的场景(比如抓拍归档),阈值可以降到 0.4。
注意:置信度阈值不是拍脑袋定的,要拿一批真实场景的图跑一遍,画出不同阈值下的漏检率和误检率曲线,根据业务能接受的平衡点来定。我见过有人直接抄别人的 0.5,结果业务场景完全不同,效果差很远。
4. 人脸对齐:把歪脸摆正的关键一步
4.1 对齐到底在解决什么问题
人脸对齐的本质,是把不同姿态、不同角度的人脸,通过几何变换统一到一个标准姿态上。为什么这一步重要?因为特征提取模型是在标准姿态的人脸上训练的,如果你喂给它一张歪着的脸,提取出来的特征和标准姿态下的特征分布不一致,比对就会失准。打个比方,对齐就像是给每个人脸拍证件照,不管你来的时候是歪头还是侧脸,最后都摆成同一个姿势再比对。
对齐依赖关键点。5 点对齐是最常用的方案,左右眼、鼻尖、左右嘴角,这 5 个点足以确定人脸的旋转、缩放和平移。有些场景会用 68 点甚至更多,但对齐本身用 5 点就够了,更多的点主要用于其他任务比如表情分析。对齐的变换一般用相似变换(旋转+缩放+平移),不做仿射或透视变换,因为相似变换能保持人脸的形状比例,不会把脸拉变形。
4.2 关键点检测的精度要求与实现
关键点检测的精度直接决定对齐质量。我的经验是,眼睛和嘴角这几个点的定位误差要控制在人脸宽度的 2% 以内,超过这个范围对齐就会明显偏。实现上,可以用专门的轻量关键点模型,也可以用带关键点分支的检测模型。后者更省事,一次推理搞定,延迟也低。关键点模型的训练数据同样需要人工标注,标注时要注意一致性,比如“左眼”到底指图像左侧还是人脸左侧,团队内部要统一,否则标出来的点会左右颠倒。
对齐后的裁剪也有讲究。标准做法是根据关键点算出变换矩阵,把眼睛对齐到固定位置,然后按固定比例裁剪出人脸区域。裁剪的边距一般留人脸宽度的 20% 到 30%,留太少会切掉下巴或额头,留太多会引入背景干扰。裁剪尺寸要和特征模型的输入尺寸匹配,常见的是 112×112 或 128×128。这里有个细节,裁剪时用双线性插值还是双三次插值,对最终特征有细微影响,我实测双三次插值在放大时更平滑,特征质量略好,但差异不大,选哪个都行。
4.3 对齐失败的兜底策略
对齐不是万能的,关键点检测失败的时候(比如严重遮挡、极端侧脸),对齐就会崩。这时候需要兜底策略。我的做法是,如果关键点置信度低于阈值,就退化成“检测框直接裁剪+缩放”,虽然效果不如对齐,但总比用错误的关键点对齐强。另外,如果检测框本身就很歪(比如长宽比异常),也要触发兜底。这个兜底逻辑在工业级系统里是必须的,因为真实场景里总有各种意外情况,不能让一个环节的失败拖垮整条流水线。
5. 特征提取:把一张脸变成一串数字
5.1 特征模型选型的核心考量
特征提取是人脸识别的核心,它的任务是把对齐后的人脸图像映射成一个固定长度的向量,通常叫 embedding,维度一般是 128、256 或 512。同一个人的不同照片,向量距离要近;不同人的向量距离要远。选型上,工业级项目我一般推荐基于 CNN 的深度特征模型,因为它在精度和速度之间比较平衡。更复杂的架构精度可能更高,但推理成本也上去了,要看你的业务能不能扛住。
选型时几个关键指标:精度(在标准测试集上的准确率)、速度(单张推理耗时)、模型大小(影响部署和内存)、鲁棒性(对光照、姿态、遮挡的容忍度)。我的经验是,不要盲目追求最高精度,因为高精度模型往往又大又慢,而工业场景对延迟很敏感。一个精度中等但速度快、鲁棒性好的模型,往往比一个精度顶尖但慢吞吞的模型更实用。具体选哪个,要拿你的真实数据跑一遍 benchmark,看综合表现。
5.2 损失函数:让同类靠近异类远离
特征模型的训练,损失函数是灵魂。最基础的是 Softmax,但它只能保证分类正确,不能保证类内紧凑、类间分离。工业级人脸识别更常用的是基于度量学习的损失,比如三元组损失、中心损失、以及各种改进版本。三元组损失的核心思想是,让锚点和正样本(同一个人)的距离小于锚点和负样本(不同人)的距离,并且留出一个 margin。这个 margin 的设置很关键,太小了学不到判别性,太大了训练不稳定,一般从 0.3 开始调。
训练三元组有个坑,就是三元组的采样策略。随机采样的话,大部分三元组都是“简单样本”,损失为 0,学不到东西。所以要用难例挖掘,专门挑那些“锚点和正样本距离已经比较远”或者“锚点和负样本距离已经比较近”的三元组来训练。在线难例挖掘是常用做法,每个 batch 里挑最难的三元组算损失。这个策略实测下来对精度提升非常明显,但训练时间也会变长,要有心理准备。
5.3 特征归一化与相似度度量
特征提取出来的向量,一般要做 L2 归一化,把向量长度统一到 1。为什么?因为归一化之后,两个向量的点积就等于余弦相似度,计算简单且稳定。相似度度量用余弦相似度或欧氏距离都行,归一化之后两者是等价的(欧氏距离的平方等于 2 减 2 倍余弦相似度)。工业系统里我一般用余弦相似度,因为它的取值范围固定在 -1 到 1 之间,阈值好设。
阈值怎么定?这要看你的业务对误识率和漏识率的要求。一般来说,相似度阈值设得越高,误识率越低但漏识率越高,反之亦然。我的做法是拿一批标注好的比对样本,画出不同阈值下的 ROC 曲线,根据业务能接受的误识率反推阈值。比如业务要求误识率低于万分之一,那就在 ROC 曲线上找到对应点,读出相似度阈值。这个阈值不是固定的,不同模型、不同数据分布下都要重新标定。
6. 向量检索:百万级人脸库怎么秒级命中
6.1 暴力检索与近似检索的取舍
人脸库小的时候(比如几千人),暴力检索完全够用,把查询向量和库里所有向量算一遍相似度,取最高的就行。但工业场景人脸库动辄几十万上百万,暴力检索的耗时是线性增长的,一百万条向量算一遍可能要几百毫秒甚至更久,扛不住高并发。这时候就要用近似最近邻检索(ANN),用少量精度损失换取数量级的速度提升。
ANN 的主流方案有几类:基于树的、基于哈希的、基于图的、基于量化的。工业场景里基于图的方案(比如 HNSW)和基于量化的方案(比如 IVF-PQ)用得比较多。HNSW 的检索速度快、召回率高,但内存占用大;IVF-PQ 内存占用小,适合超大规模,但召回率略低。选哪个要看你的库大小和内存预算。我的经验是,百万级以下用 HNSW 比较舒服,千万级以上考虑 IVF-PQ。
6.2 索引构建与参数调优
以 HNSW 为例,几个关键参数:M(每个节点的连接数)、efConstruction(构建时的候选集大小)、efSearch(检索时的候选集大小)。M 越大,图越密,召回率越高但内存和构建时间也越大,一般设 16 到 64。efConstruction 越大,索引质量越好,一般设 100 到 500。efSearch 是检索时调的,越大召回率越高但越慢,可以在线调整,根据业务对延迟的要求来定。
构建索引的时候有个坑,就是数据要分批插入,不要一次性全塞进去,否则内存容易爆。另外,索引构建完之后要拿一批查询样本测召回率,召回率低于业务要求的要调参数重建。我一般要求召回率在 95% 以上,低于这个值就要检查参数或者换方案。还有,索引不是建一次就完事,人脸库是动态增长的,新注册的人脸要能实时插入索引,这要求索引方案支持增量更新,HNSW 是支持的,IVF-PQ 增量更新相对麻烦一些。
6.3 检索结果的二次校验
ANN 检索出来的是候选集,通常取 Top-K(比如 Top-10),然后对这 K 个候选做精确的相似度计算,再结合阈值判断是不是同一个人。这一步叫二次校验或重排序。为什么要做?因为 ANN 是近似的,可能把真正最像的漏掉,也可能把不够像的排前面。二次校验用精确计算把候选集重新排一遍,能提升最终准确率。K 的取值一般 10 到 100,太小了可能漏掉正确答案,太大了二次校验的开销上去了。
二次校验之后,还要做业务层面的判断。比如,最高相似度低于阈值,就判定为“未注册”;最高相似度和第二高相似度差距太小,就判定为“存疑”,转人工审核。这些业务规则是工业级系统必备的,因为模型不可能 100% 准,总要有兜底机制。我一般会设两个阈值:一个高阈值直接通过,一个低阈值直接拒绝,中间的转人工。这样既保证了自动化效率,又控制了风险。
7. 部署与推理加速:让模型真正跑起来
7.1 模型量化与剪枝的实操
训练好的模型往往又大又慢,直接部署到生产环境可能扛不住。量化是最常用的加速手段,把浮点权重转成低精度(比如 INT8),模型大小能缩小到四分之一,推理速度也能提升两三倍,精度损失通常在一个百分点以内。量化的关键是校准集的选择,要用真实场景的数据做校准,否则量化误差会偏大。我一般从训练集里抽一千张左右的真实样本做校准,覆盖各种光照和角度。
剪枝是另一条路,把模型中不重要的权重或通道去掉,减小模型规模。剪枝的难点在于怎么判断哪些不重要,常用的是基于权重幅值或者基于通道的 L1 范数。剪枝之后一般要微调几轮,把精度找回来。我的经验是,剪枝对精度的伤害比量化大,所以如果只是为了加速,优先用量化,剪枝作为补充。两者可以叠加,先剪枝再量化,但叠加之后精度损失要仔细评估。
7.2 推理引擎选型与批处理
推理引擎的选择直接影响部署效率。常见的有几类:通用深度学习推理框架、针对特定硬件的加速库、以及各家硬件厂商的专用引擎。选型时要考虑你的硬件平台、模型格式、以及是否需要跨平台。我的建议是,先在目标硬件上把几个候选引擎都跑一遍 benchmark,看实际延迟和吞吐,别只看理论指标。同一个模型在不同引擎上的表现可能差好几倍。
批处理是提升吞吐的关键。单张推理的时候,GPU 利用率往往很低,因为计算量太小。把多张图攒成一个 batch 一起推理,能显著提升吞吐。但 batch 太大会增加延迟,所以要权衡。工业场景里,如果对延迟不敏感(比如离线归档),batch 可以设大一点,比如 32 或 64;如果对延迟敏感(比如实时门禁),batch 设小一点,甚至用动态 batch。这里有个技巧,用异步推理,把预处理、推理、后处理流水线化,能进一步压榨硬件性能。
7.3 服务化与高可用设计
模型部署成服务,要考虑高可用。单点部署肯定不行,一台机器挂了整个系统就瘫了。我的做法是至少部署两个实例,前面挂负载均衡,一个挂了另一个顶上。服务要支持健康检查,定期探测实例状态,不健康的自动摘除。另外,模型加载要支持热更新,新模型上线不用重启服务,避免停机。
监控也是必须的。要监控的指标包括:QPS、延迟分布(P50、P95、P99)、错误率、GPU 利用率、内存占用。延迟的 P99 比平均值更重要,因为平均值会被大量快请求拉低,掩盖了慢请求的问题。我一般要求 P99 延迟在业务可接受范围内,比如 200ms 以内。错误率超过阈值要告警,及时排查。这些监控数据也是后续优化的依据,哪里慢、哪里错,一目了然。
8. 常见问题与排查技巧实录
8.1 识别率突然下降怎么排查
识别率下降是工业系统最常见的问题,排查要有章法。我的排查顺序是:先看数据,再看检测,再看对齐,最后看特征和检索。数据层面,检查输入图像有没有异常,比如摄像头脏了、曝光参数变了、传输丢包导致图像损坏。检测层面,看检测框是不是变歪了、漏检变多了。对齐层面,看关键点是不是偏了。特征层面,看 embedding 分布有没有漂移。检索层面,看索引是不是损坏了或者没更新。
这个顺序的逻辑是从上游到下游,因为上游的问题会传导到下游。我遇到过一次识别率暴跌,最后查出来是摄像头镜头脏了,图像整体模糊,检测框质量下降,导致后面全崩。所以别一上来就怀疑模型,先看最前端的输入。排查的时候要善用可视化,把检测框、关键点、对齐结果都画出来看,比看数字直观得多。
8.2 误识和漏识的平衡怎么调
误识(把 A 认成 B)和漏识(没认出 A)是一对矛盾,调阈值只能此消彼长。要同时改善,只能从模型和数据入手。误识多,说明模型的判别性不够,类间距离太近,要加强度量学习,或者补充难负样本。漏识多,说明模型对某些场景不鲁棒,要补充对应场景的训练数据。我的经验是,先把误识压到业务可接受的范围,因为误识的风险通常比漏识大(比如门禁误识放陌生人进去,后果严重)。漏识可以通过多帧投票、多次尝试来缓解。
多帧投票是个实用技巧。视频流里同一个人会出现多帧,把多帧的识别结果综合起来,能显著降低误识和漏识。最简单的做法是多数投票,复杂一点可以按质量加权(清晰的正脸权重高,模糊的侧脸权重低)。我实测下来,多帧投票能把误识率降低一个数量级,代价是增加了一点延迟。对于实时性要求不那么极致的场景,强烈推荐加上。
8.3 常见问题速查表
| 问题现象 | 可能原因 | 排查方向 | 解决思路 |
|---|---|---|---|
| 识别率整体偏低 | 训练数据与场景不匹配 | 对比训练集和现场数据分布 | 补充现场数据重新训练 |
| 侧脸识别差 | 侧脸样本不足 | 统计侧脸占比 | 上采样侧脸样本 |
| 暗光识别差 | 暗光样本不足或增强不够 | 检查暗光样本比例 | 补充暗光数据+亮度增强 |
| 小脸检测不到 | 输入分辨率太低 | 统计最小人脸尺寸 | 提高输入分辨率 |
| 密集人脸漏检 | NMS 阈值太低 | 检查 NMS 参数 | 调高阈值或用 Soft-NMS |
| 对齐后脸歪 | 关键点精度不够 | 可视化关键点 | 重新标注或换关键点模型 |
| 检索慢 | 索引参数不当 | 测检索延迟 | 调 efSearch 或换 ANN 方案 |
| 内存爆 | 索引太大或 batch 太大 | 监控内存占用 | 减小索引规模或 batch |
| 延迟高 | 模型太大或没量化 | 测单张推理耗时 | 量化+剪枝+推理引擎优化 |
| 服务不稳定 | 单点部署无监控 | 检查部署架构 | 多实例+负载均衡+监控 |
8.4 几个踩过的坑和独家经验
第一个坑,别在训练集上评估模型。我见过有人拿训练集当验证集,准确率 99.9%,上线就崩。一定要留出独立的验证集和测试集,而且测试集要尽量贴近真实场景。第二个坑,别忽略数据的时间跨度。人脸会变,发型会变,年龄会变,如果训练数据都是几年前的,对现在的脸识别率会下降。要定期用新数据更新模型。第三个坑,别把阈值写死在代码里。阈值要可配置,因为不同场景、不同时期的最优阈值可能不同,写死了改起来很麻烦。
还有个经验,就是模型上线前一定要做压力测试。用真实场景的数据,模拟高并发,看系统的延迟、吞吐、错误率。我遇到过一次上线后才发现,某个环节在并发高的时候会超时,导致整个请求失败。压力测试能提前暴露这些问题。测试的时候要关注 P99 延迟,而不是平均值,因为平均值会骗人。另外,要做好降级预案,某个环节挂了或者超时了,要有兜底逻辑,不能让整个请求失败。
最后分享一个关于迭代节奏的经验。工业级系统不是一次做完就完事,而是要持续迭代。我的做法是每周做一次数据回流和难例分析,每月做一次模型评估和阈值标定,每季度做一次大版本更新。这个节奏既能保证系统持续优化,又不会因为频繁更新引入不稳定。每次更新都要有回滚方案,新版本出问题能快速切回旧版本。这套机制跑顺了,系统的识别率会随着时间稳步提升,而不是上线即巅峰然后慢慢衰减。