AI图像内容安全:NSFW检测模型冷启动问题与轻量级热身技能实践
1. 项目概述一个为AI图像内容安全“热身”的技能最近在折腾AI图像生成和内容审核相关的东西发现一个挺有意思的项目叫huangji6693-max/x-nsfw-warmup-skill。光看这个标题可能有点摸不着头脑但如果你也在这个领域里踩过坑大概能猜到它想解决什么问题。简单来说这是一个为AI模型特别是那些处理图像内容的模型进行“热身”或“预训练”的技能或工具其核心目标很可能是为了提升模型在识别和过滤不适宜内容Not Safe For Work, NSFW方面的初始性能和稳定性。在AI图像生成、内容审核、社交平台自动过滤等场景下NSFW检测是一个刚需也是一个技术难点。直接拿一个预训练好的模型上线经常会遇到“冷启动”问题模型对某些特定风格、模糊边界或新出现的内容形式反应迟钝甚至误判导致要么漏放违规内容要么误伤正常创作。这个项目名里的“warmup”热身和“skill”技能两个词就点明了它的价值——它不是要替代一个完整的NSFW分类器而是为现有的检测流程增加一个前置的、轻量级的“预热”环节让主模型能更快进入状态减少初期的不稳定表现。这个项目适合所有需要集成图像内容安全能力的开发者、算法工程师以及产品经理。无论你是在搭建一个AI绘画社区的内容审核后台还是在为一个社交应用添加图片自动过滤功能甚至是在训练自己的图像生成模型时需要构建安全护栏了解并应用这类“热身技能”都能帮你更平滑地度过模型部署初期的阵痛期提升整体系统的鲁棒性和用户体验。接下来我就结合自己的实践经验深入拆解一下这类工具的设计思路、核心实现以及那些官方文档里不会写的实操细节。2. 核心思路与方案选型为什么需要“热身”2.1 “冷启动”问题的根源剖析为什么一个训练好的NSFW检测模型上线初期会表现不稳定这背后有几个关键原因理解它们才能明白“热身”的必要性。首先数据分布偏移。模型在训练时使用的数据集无论多么庞大都无法百分之百覆盖线上真实、动态的数据流。线上用户的图片风格、拍摄角度、压缩质量、甚至是一些刻意规避检测的“对抗性样本”都可能与训练数据存在差异。模型初次遇到这些“陌生”样本时其内部神经元的激活模式会处于一个未经验证的状态输出置信度可能波动很大。其次模型初始化与微调间隙。很多项目在部署时会采用在大型通用数据集如ImageNet上预训练的模型作为基础然后在特定标注的NSFW数据上进行微调。然而从微调完成到部署上线模型参数是固定的。它没有机会在真实的、无标注的线上流量中进行快速的、自适应的“再校准”。这个间隙就是模型表现的脆弱期。最后单一阈值判定的局限性。NSFW检测通常输出一个0到1之间的分数然后设定一个阈值比如0.5来判定是否违规。在冷启动期由于上述原因模型输出的分数分布可能整体偏高或偏低导致固定的阈值不再适用从而引发大量误报或漏报。2.2 “热身技能”的定位与价值基于以上问题x-nsfw-warmup-skill这类项目的核心定位就不是一个重型的、端到端的分类器而是一个轻量级、自适应、前置的校准与增强模块。它的价值体现在几个层面快速适应在模型部署后的最初一段时间可能是几个小时或几天利用实际流经的图片数据无需人工标注快速感知当前数据分布的特点对主模型进行微小的调整或为其输出提供校准参数。不确定性感知除了给出“是否NSFW”的判断一个优秀的“热身技能”应该能评估模型对当前输入图片的“不确定程度”。对于高不确定性的图片可以采取更保守的策略如转入人工审核队列而不是武断地通过或拦截。多模型协同它可能本身就是一个极其轻量的模型如小型卷积神经网络或Transformer或者是一套规则与特征提取逻辑。它的预测结果可以与主模型的结果进行加权融合或作为先验知识提升整体决策的可靠性。降低运营成本通过在冷启动期有效减少误判可以显著降低人工复审团队的压力避免因误杀正常内容而引发的用户投诉从而在业务上线初期就建立良好的信任。在方案选型上这类技能通常不会选择从头训练一个大型模型而是倾向于以下几种路径知识蒸馏用一个大型、精准但缓慢的NSFW模型作为“教师”来训练一个轻量级的“学生”模型作为热身技能。特征提取与浅层分类器使用预训练模型如CLIP、EfficientNet提取图像特征然后接一个简单的逻辑回归或小型神经网络进行分类。这个组合训练快部署开销小。在线学习与阈值动态调整设计算法根据近期一批图片的模型输出分数分布动态调整判定阈值或者对模型最后一层的偏置项进行微调。集成学习结合多个不同架构的轻量级模型的预测结果通过投票或平均来提升热身阶段的稳定性。3. 核心组件与实现细节拆解要构建一个有效的x-nsfw-warmup-skill我们需要拆解几个核心组件。虽然看不到该项目的具体代码但我们可以根据其目标推导出它必然包含或涉及的关键部分。3.1 图像预处理与特征工程管道任何图像分析模型的第一步都是预处理。对于NSFW检测预处理的目标是标准化输入并尽可能保留对判别敏感的信息同时剔除干扰。尺寸归一化将所有输入图像缩放到固定尺寸如224x224或384x384。这里的一个关键细节是缩放策略。简单粗暴的拉伸会导致形变可能影响模型对肢体比例、物体形状的判断而这些恰恰是NSFW检测的重要线索。更优的做法是采用“保持长宽比的缩放边缘填充Padding”。例如先将短边缩放到目标尺寸长边按比例缩放然后在长边两侧进行灰度或边缘像素填充。注意填充的颜色需要谨慎选择。黑色或白色填充可能会在图像边界引入不自然的硬边缘干扰模型。一种常见的做法是使用图像边缘像素的平均值进行填充或者使用镜像填充。颜色空间与归一化通常将图像从RGB通道转换到模型期望的格式。许多预训练模型要求输入进行特定的归一化即每个通道减去一个均值如[0.485, 0.456, 0.406]并除以一个标准差如[0.229, 0.224, 0.225]。这一步必须与后续使用的预训练特征提取器严格保持一致。数据增强用于训练阶段在训练“热身技能”模型时为了增强其鲁棒性需要对训练数据进行增强。但对于NSFW任务增强方式需要特别设计可以安全使用的随机水平翻转、小幅度的亮度/对比度调整、添加高斯噪声。需要谨慎或避免的随机裁剪可能裁掉关键判别区域、大幅度的旋转改变方向可能影响语义、颜色抖动过度改变肤色等信息。我们的目标是让模型学习到本质特征而不是被增强引入的无关变化所干扰。3.2 轻量级模型架构选择作为“热身”技能模型必须足够轻量以实现低延迟的实时或准实时处理。以下是几种可行的架构选择及其考量MobileNetV3 / EfficientNet-Lite这些是专为移动和边缘设备设计的网络在精度和速度之间取得了很好的平衡。它们可以作为不错的主干网络Backbone用于提取图像特征。Vision Transformer (ViT) 小型变体如ViT-Tiny或ViT-Small。Transformer架构在图像分类上表现强劲小型变体参数量相对可控。如果“热身技能”需要更好地理解全局上下文关系对于某些需要场景理解的NSFW内容可能有帮助ViT是一个值得考虑的选项。自定义的浅层CNN如果对极端轻量化有要求可以设计一个只有4-6个卷积层的简单网络。虽然精度可能不及上述模型但推理速度极快适合作为第一道快速过滤网。架构选型心得不要盲目追求最先进的模型。对于“热身”任务推理速度和资源消耗往往是比极致精度更优先的指标。一个在99%情况下与大型模型判断一致但速度快10倍的轻量模型其业务价值更大。通常我会先用EfficientNet-Lite作为基线如果速度不达标再考虑更轻量的模型。3.3 不确定性量化与校准模块这是区分一个普通分类器和一个智能“热身技能”的关键。我们需要让模型知道自己“不知道”什么。温度缩放这是后处理校准中最简单有效的方法之一。在模型的softmax层之前引入一个可学习的“温度”参数T将逻辑输出除以T后再进行softmax。在训练完成后用一个小的校准集可以是初始的一部分线上数据来优化这个T参数使得模型输出的置信度更接近其真实的正确概率。# 伪代码示例温度缩放 logits model(image) # 模型原始输出 temperature 1.5 # 学习到的温度参数 calibrated_probs torch.softmax(logits / temperature, dim-1)蒙特卡洛Dropout在推理时多次开启Dropout让模型进行多次前向传播。由于Dropout的随机性每次输出会略有不同。通过统计这多次预测的分布比如计算预测概率的方差可以度量模型的不确定性。方差越大说明模型越不确定。集成模型训练多个结构相同但初始化不同的轻量模型或者使用不同的数据子集训练。推理时综合所有模型的预测结果。集成模型之间的分歧程度如预测熵可以作为不确定性的度量。实操要点对于线上服务蒙特卡洛Dropout和模型集成会增加计算开销。温度缩放是性价比最高的首选方案。它几乎不增加推理时间却能显著改善置信度的可靠性。我们可以设定一个规则当校准后的NSFW概率处于一个“模糊区间”如0.4-0.6时或者当不确定性分数超过某个阈值时就将该图片标记为“需要人工复审”从而实现流量的精细化管控。4. 端到端实现流程与核心代码解析假设我们要从零开始实现一个类似x-nsfw-warmup-skill的核心功能。以下是一个基于PyTorch的简化版流程涵盖了训练和部署的关键环节。4.1 环境准备与依赖安装首先需要一个干净的Python环境。建议使用Conda进行管理。# 创建并激活环境 conda create -n nsfw-warmup python3.9 conda activate nsfw-warmup # 安装核心依赖 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cpu # 根据CUDA版本调整 pip install timm # 一个优秀的PyTorch图像模型库包含各种预训练模型 pip install opencv-python pillow pandas scikit-learn pip install onnx onnxruntime # 可选用于模型导出和优化部署4.2 数据准备与加载器编写NSFW数据集的获取和处理需要格外谨慎。这里假设我们已经有了一个合规的、标注好的数据集例如图片路径和对应的标签0/1。import torch from torch.utils.data import Dataset, DataLoader from PIL import Image import pandas as pd import torchvision.transforms as T class NSFWDataset(Dataset): def __init__(self, csv_file, img_dir, transformNone, is_trainTrue): self.annotations pd.read_csv(csv_file) self.img_dir img_dir self.is_train is_train # 定义基础转换 base_transform T.Compose([ T.Resize((256, 256)), # 先缩放到稍大尺寸 T.ToTensor(), T.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ]) # 训练时增加增强 if is_train and transform is None: self.transform T.Compose([ T.RandomResizedCrop(224), # 随机裁剪到目标尺寸 T.RandomHorizontalFlip(p0.5), # 谨慎添加颜色扰动 T.ColorJitter(brightness0.1, contrast0.1), T.ToTensor(), T.Normalize(mean[0.485, 0.456, 0.406], std[0.229, 0.224, 0.225]), ]) else: self.transform transform or base_transform def __len__(self): return len(self.annotations) def __getitem__(self, idx): img_path os.path.join(self.img_dir, self.annotations.iloc[idx, 0]) image Image.open(img_path).convert(RGB) label self.annotations.iloc[idx, 1] if self.transform: image self.transform(image) return image, torch.tensor(label, dtypetorch.float32) # 创建数据加载器 train_dataset NSFWDataset(train.csv, ./images/train, is_trainTrue) val_dataset NSFWDataset(val.csv, ./images/val, is_trainFalse) train_loader DataLoader(train_dataset, batch_size32, shuffleTrue, num_workers4) val_loader DataLoader(val_dataset, batch_size32, shuffleFalse, num_workers4)关键细节数据加载器的num_workers设置对于训练效率至关重要。通常设置为CPU核心数的2-4倍。但要注意如果数据存储在慢速硬盘上过多的worker可能导致I/O争用反而降低速度。4.3 模型定义与训练循环我们选择timm库中的efficientnet_lite0作为主干网并添加一个自定义的分类头。import timm import torch.nn as nn import torch.optim as optim class WarmupNSFWModel(nn.Module): def __init__(self, num_classes1, pretrainedTrue): super().__init__() # 使用预训练的efficientnet_lite0作为特征提取器 self.backbone timm.create_model(efficientnet_lite0, pretrainedpretrained, num_classes0, global_pool) backbone_features self.backbone.num_features # 通常是1280 # 全局平均池化 self.global_pool nn.AdaptiveAvgPool2d(1) # 分类头一个简单的全连接层输出单个值用于二分类sigmoid self.classifier nn.Sequential( nn.Dropout(p0.2), # 加入Dropout防止过拟合也为后续的不确定性估计留可能 nn.Linear(backbone_features, num_classes) ) def forward(self, x): features self.backbone(x) # 形状: [B, C, H, W] pooled self.global_pool(features) # 形状: [B, C, 1, 1] flattened pooled.view(pooled.size(0), -1) # 形状: [B, C] logits self.classifier(flattened) # 形状: [B, 1] return logits.squeeze(1) # 形状: [B] # 初始化模型、损失函数、优化器 device torch.device(cuda if torch.cuda.is_available() else cpu) model WarmupNSFWModel().to(device) criterion nn.BCEWithLogitsLoss() # 二分类交叉熵损失内部包含sigmoid optimizer optim.AdamW(model.parameters(), lr1e-4, weight_decay1e-4) # 使用AdamW和权重衰减 scheduler optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max10) # 余弦退火学习率调度 # 训练循环简化版 def train_epoch(model, loader, optimizer, criterion, device): model.train() running_loss 0.0 for images, labels in loader: images, labels images.to(device), labels.to(device) optimizer.zero_grad() outputs model(images) loss criterion(outputs, labels) loss.backward() # 可以添加梯度裁剪防止训练不稳定 torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0) optimizer.step() running_loss loss.item() * images.size(0) return running_loss / len(loader.dataset) # 验证循环 def validate(model, loader, criterion, device): model.eval() running_loss 0.0 correct 0 total 0 with torch.no_grad(): for images, labels in loader: images, labels images.to(device), labels.to(device) outputs model(images) loss criterion(outputs, labels) running_loss loss.item() * images.size(0) # 将sigmoid输出转换为0/1预测 preds (torch.sigmoid(outputs) 0.5).float() correct (preds labels).sum().item() total labels.size(0) val_loss running_loss / total val_acc correct / total return val_loss, val_acc训练技巧学习率预热在训练最开始的前几个epoch使用非常小的学习率然后逐渐增加到预设值这有助于模型稳定收敛。标签平滑对于可能存在噪声标注的NSFW数据集可以在损失函数中使用标签平滑Label Smoothing防止模型对预测结果过于自信这也有助于模型校准。早停持续监控验证集损失当其在连续多个epoch不再下降时停止训练避免过拟合。4.4 模型校准与导出训练完成后我们需要对模型进行校准并导出为适合部署的格式。def calibrate_temperature(model, calib_loader, device): 使用验证集的一部分作为校准集学习温度参数T model.eval() logits_list [] labels_list [] with torch.no_grad(): for images, labels in calib_loader: images images.to(device) logits model(images).cpu() # 获取原始逻辑输出 logits_list.append(logits) labels_list.append(labels) all_logits torch.cat(logits_list) all_labels torch.cat(labels_list) # 将温度参数T设置为可优化变量 temperature nn.Parameter(torch.ones(1) * 1.5) optimizer optim.LBFGS([temperature], lr0.01, max_iter100) def eval(): optimizer.zero_grad() # 使用温度缩放后的概率计算负对数似然损失 cal_probs torch.sigmoid(all_logits / temperature) loss nn.functional.binary_cross_entropy(cal_probs, all_labels) loss.backward() return loss optimizer.step(eval) print(fCalibrated temperature: {temperature.item():.4f}) return temperature.item() # 假设calib_loader是验证集的一部分 best_temperature calibrate_temperature(model, calib_loader, device) # 导出模型示例为TorchScript model.eval() example_input torch.randn(1, 3, 224, 224).to(device) traced_script_module torch.jit.trace(model, example_input) traced_script_module.save(nsfw_warmup_model.pt) # 保存温度参数和元数据 import json metadata { model_type: efficientnet_lite0, input_size: [224, 224], mean: [0.485, 0.456, 0.406], std: [0.229, 0.224, 0.225], temperature: best_temperature, threshold_suggested: 0.5, # 初始阈值可根据业务调整 } with open(model_metadata.json, w) as f: json.dump(metadata, f, indent2)部署考虑在生产环境中我们可能希望使用ONNX格式以获得更广泛的运行时支持如ONNX Runtime, TensorRT和更好的性能优化。可以使用torch.onnx.export将PyTorch模型转换为ONNX格式。记住导出时也需要把预处理归一化和后处理sigmoid 温度缩放的逻辑清晰地定义出来或者确保部署端能正确实现。5. 集成策略与线上服务架构“热身技能”最终需要无缝集成到现有的内容审核流水线中。这里提供两种典型的集成架构。5.1 异步预热与缓存策略这是对线上服务侵入最小、最安全的方式。架构如下图所示文字描述主流程用户上传图片 - 主NSFW检测模型大型、精准进行判断 - 根据结果执行动作通过/拦截/复审。异步旁路同时图片被异步发送到“热身技能”服务队列。热身处理热身技能快速处理该图片产生两个关键输出a) 一个初步的NSFW分数经过校准b) 一个不确定性分数。结果缓存将图片哈希值 热身分数 不确定性分数存入一个短期缓存如RedisTTL设置为几分钟到几小时。决策辅助如果主模型对该图片的判断置信度很高例如分数非常接近0或1则忽略缓存结果。如果主模型判断置信度中等或者主模型服务超时/出错则查询缓存。若缓存中存在该图片的热身结果且热身分数很高例如0.7则可以直接判定为高风险触发复审或拦截。若热身分数处于模糊区间且不确定性高则标记为“急需人工复审”提升其在审核队列中的优先级。模型更新定期例如每小时分析缓存中积累的数据计算热身模型预测与人工复审结果如果最终有的话的差异。如果发现系统性偏差可以触发一个轻量级的在线学习流程微调热身模型的温度参数甚至最后一层权重。这种策略的优势完全解耦不影响主流程的稳定性。热身技能即使失效也不会导致服务中断。它主要起到“加速”和“兜底”的作用。5.2 串联过滤与降级策略这是一种更主动但风险稍高的方式将热身技能置于主流程之前。第一道过滤用户上传图片 - 先经过“热身技能”进行极速判断。高置信度拦截/放行如果热身技能以极高置信度判定为NSFW如分数0.9则直接拦截并记录日志。这可以过滤掉大部分明显的违规内容减轻后端主模型压力。如果热身技能以极高置信度判定为安全如分数0.1则直接放行。模糊区间转发对于处于中间模糊区间的图片如0.1 分数 0.9将其转发给后续更精确但更慢的主NSFW模型进行最终裁决。降级开关必须为这个热身技能设置一个功能开关。当监控发现热身技能的误杀率突然升高时可以立即关闭此串联过滤让所有流量直接走主模型确保服务基本功能不受损。这种策略的优势能显著降低对主模型的调用量节约计算资源并降低整体延迟因为大部分简单图片被快速处理了。关键挑战必须确保热身技能在“高置信度”区域的准确率极高否则会导致大量误操作。这需要通过严格的阈值调优和持续的监控来保障。6. 监控、评估与迭代优化部署上线只是开始持续的监控和优化才是保证“热身技能”长期有效的关键。6.1 核心监控指标需要建立一套仪表盘实时跟踪以下指标指标计算方式健康标准与应对措施服务可用性请求成功率、平均响应时间、P99延迟成功率99.9%平均延迟50ms。超标需检查服务负载或网络。流量分布各分数区间的图片数量分布如[0,0.1], (0.1,0.3], ...分布应相对稳定。突然变化可能预示数据分布偏移或攻击。与主模型一致性热身技能与主模型结果一致的比率在两者都判断的样本中通常应保持在85%以上。大幅下降可能意味着热身技能失效或主模型更新。人工复审推翻率被热身技能标记但经人工复审后推翻的比例推翻率应维持在一个较低水平如5%。持续升高需重新评估阈值或模型。不确定性分数分布高不确定性如0.6图片的比例比例突然增高可能出现了模型未曾见过的新类型内容。6.2 评估与迭代流程不能只依赖线上监控还需要定期进行离线评估。每周/每月抽样评估从线上流量中随机抽取一定数量如1000张的图片由专业审核人员进行双重盲审标注形成一个小型的“黄金测试集”。计算关键指标精确率、召回率、F1分数在当前的业务阈值下计算。ROC曲线与AUC评估模型整体的排序能力。校准曲线检查模型输出的置信度是否准确。理想情况下预测为80%概率是NSFW的图片中应该有大约80%确实是的。A/B测试任何对模型、阈值或策略的修改都应先通过A/B测试。例如将新版本的热身技能部署到1%的流量上对比其与旧版本在关键业务指标如误拦截率、人工审核负载上的差异。迭代触发当出现以下情况时应考虑启动模型迭代黄金测试集上的F1分数持续下降超过一定幅度。线上人工复审推翻率持续上升。业务需求变化如需要检测新类型的违规内容。迭代时的数据策略收集线上被热身技能“不确定”区域标记的图片以及被人工复审推翻的案例加入到训练数据中。这是提升模型在困难样本上表现的最有效方法。但务必注意数据清洗和去重防止引入偏见。7. 常见陷阱与实战避坑指南在实际开发和运营这类系统的过程中我踩过不少坑这里分享一些血泪教训。7.1 数据与标注相关坑训练数据偏见导致“盲区”。如果训练数据中缺乏某种特定文化背景、艺术风格或拍摄条件的图片模型会对这类图片完全失效。例如数据集中全是现代摄影那么古典油画风格的人体艺术可能被误判。避坑尽可能使用来源多样、覆盖广泛的数据集进行预训练或微调。定期用线上“不确定”样本和误判样本对训练集进行查漏补缺。坑标注不一致与噪声。NSFW标注具有很强的主观性不同标注员的标准可能不同甚至同一个人在不同时间标准也会波动。这会导致标签噪声严重影响模型学习上限。避坑采用多人交叉标注并通过计算标注者间信度来评估标注质量。对于分歧大的样本由资深审核员仲裁。在训练时可以采用带噪声标签的学习算法或标签平滑技术。7.2 模型与工程相关坑过度依赖单一阈值。业务方常常希望有一个“神奇”的阈值一劳永逸。但现实是最佳阈值会随着数据分布、业务容忍度的变化而漂移。避坑建立动态阈值机制。可以基于近期一段时间的模型输出分布如过去24小时使用百分位数例如设定让5%的图片被拦截的阈值或PR曲线上的最优点如最大化F1分数来动态调整阈值。同时提供“模糊区间”而非硬性判断。坑忽略模型退化。认为模型部署后就一劳永逸。互联网内容日新月异今天的有效模型明天可能就出现漏洞。避坑如前所述建立常态化的监控、评估和迭代流程。将模型迭代视为一个持续的过程而非一次性项目。坑热身技能本身成为性能瓶颈。如果热身模型设计得过于复杂或者预处理逻辑低效其带来的延迟可能抵消甚至超过它节省的时间。避坑对热身技能的推理链路进行性能剖析。使用工具分析每一步的耗时。考虑使用更高效的图像解码库如libjpeg-turbo、将预处理逻辑用C实现、或者使用TensorRT/OpenVINO等工具对模型进行推理优化。7.3 业务与合规相关坑误杀合法内容引发用户投诉。这是最大的业务风险。一张被误判的家庭合影或医疗教育图片可能导致用户强烈不满。避坑设立便捷的申诉通道并确保申诉图片能快速得到人工复核。将申诉案例作为最重要的负样本反馈到模型迭代中。在系统设计上对于低置信度的拦截可以向用户展示更友好的提示如“您的图片可能需要进一步审核预计需要X分钟”而非冷冰冰的“违规”。坑未能适应业务场景变化。社区初期可能对内容尺度比较宽松随着发展可能收紧政策。反之亦然。避坑保持与产品、审核团队的紧密沟通。任何内容政策的调整都需要转化为对模型阈值或训练目标的调整。建立模型效果与业务指标如用户举报率、社区氛围评分的关联分析。构建一个像x-nsfw-warmup-skill这样的系统技术只是骨架真正的血肉来自于对业务场景的深刻理解、对数据闭环的精心设计以及持续不断的运营调优。它不是一个可以“设置好就忘记”的工具而是一个需要精心培育和持续观察的智能体。从我的经验来看成功的系统往往不是那个初始精度最高的而是那个能最快感知变化、最稳当地适应变化的那一个。