ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Python多模态识别框架下的虚假新闻检测与特征融合

Python多模态识别框架下的虚假新闻检测与特征融合 简介这是一份完整的基于Python的多模态虚假新闻检测项目源码及配套文档适合计算机、人工智能等相关专业的在校学生、教师或企业开发者用于课程设计、毕业设计或项目初期验证。项目中融合了文本与图像等多模态特征进行虚假新闻识别代码结构清晰包含基于BERT的模型实现、特征融合与调参脚本等模块。压缩包共39个文件以16个Python脚本为主辅以Markdown/TXT说明文档、Shell运行脚本、JSON配置及TSV数据文件整体大小约350KB便于快速浏览与部署目录结构也比较清晰。目前已有296人次学习下载。读者可获得完整的模型代码、训练与预测脚本、环境依赖清单packages.txt以及项目说明文档既能直接复现多模态识别流程也可基于现有代码进行改进用于毕设或课题研究。1. 基于 Python 的虚假新闻检测多模态识别到底在解决什么问题2024 年之后纯文本的虚假新闻检测已经不太够用了。大量伪造内容开始走“真假拼接”的路线新闻正文是从正规媒体上扒下来的配图却是用生成模型伪造的或者反过来配图是真实的但文字描述被恶意篡改。这类样本如果只做文本分类特征非常接近真实新闻检测模型在这种场景下集体翻车。基于 Python 的虚假新闻检测多模态识别就是把新闻正文文本和配图图像放在同一个模型里做联合判断通过文本与图像之间的语义一致性、来源可信度、编辑痕迹等互补信号把单模态模型漏掉的那部分假新闻重新捞回来。这个方案适合已经在做文本分类、想往多模态方向扩展的从业者也适合需要给内容审核系统加一道视觉校验的团队。它解决的不是“识别所有假新闻”而是“识别单靠文本看不出来的假新闻”这套思路落地后能将验证集 Macro-F1 从 0.83 附近拉到 0.91 左右。2. 搭建多模态识别框架文本分支、图像分支和融合层多模态识别的框架搭建核心是三个分支的选择与配合文本特征提取、图像特征提取、以及把两边特征压到同一尺度再融合的分类层。很多人第一次做多模态时习惯把文本和图像的特征直接拼起来丢给分类器结果模型收敛慢、准确率上不去。问题不在数据量而在特征维度不匹配——5000 维的 TF-IDF 文本向量和 2048 维的图像特征拼接后梯度更新会被高维分支主导。常见的做法是先做投影对齐再融合这也是这个项目源码里最核心的套路。2.1 环境选型Python 3.10、PyTorch 2.x 和 Transformers 库的搭配搭建环境阶段有一个先决条件Python 版本不能太低。PyTorch 2.x 在 3.8 以下版本上会出现算子兼容问题而 Transformers 库的新版特性也需要 Python 3.9 以上。推荐直接用 Python 3.10这个版本在虚拟环境和依赖管理上踩的坑最少。conda create -n fake_news python3.10 conda activate fake_news pip install torch torchvision transformers scikit-learn pandas pillow逻辑说明torch和torchvision负责图像分支的模型加载与训练transformers用来调用预训练视觉模型和文本编码器scikit-learn提供 TF-IDF 向量化和评估指标。装完以后用python -c import torch; print(torch.__version__)验证安装结果这个习惯能省掉不少环境问题的排查时间。参数说明如果机器没有 NVIDIA GPUtorch会默认安装 CPU 版本性能会差一些但不是不能用。四核 CPU 的笔记本跑一轮推理大约 8 秒优化后可以压到 2 秒以内这个后面在推理部分单独展开。GPU 显存低于 6G 时建议把图像编码器的输入尺寸从 224 降到 168能少占约一半显存。2.2 文本分支TF-IDF 和词向量怎么选文本特征在虚假新闻检测里的作用比大多数人想的要大。标题党是第一个特征正文和图片的语义错位是第二个特征。起始阶段不用直接上 BERT成本太高先用 TF-IDF 拿到基准线。from sklearn.feature_extraction.text import TfidfVectorizer vectorizer TfidfVectorizer(ngram_range(1, 2), stop_wordsenglish, max_features5000) X_train_tfidf vectorizer.fit_transform(df[clean_text]) X_test_tfidf vectorizer.transform(df_test[clean_text])逻辑说明ngram_range(1, 2)让特征包含单个词和连续双词能抓到“震惊”“绝对真相”这类典型的标题党短语max_features5000控制维度避免在新闻数据集上把稀疏矩阵撑得过大。fit_transform只用在训练集上测试集只能用transform否则会把测试集的词汇混进词典造成特征泄漏这在虚假新闻检测里是常见的评测虚高来源。参数说明stop_wordsenglish对中文文本无效中文场景需要用jieba先分词再把分词结果传给 TF-IDF。检测结果里如果出现“不实信息”和“不实”被拆成两个特征的情况多半是分词粒度没调对需要看analyzer参数是否生效。2.3 视觉分支用预训练 CNN 提取新闻配图特征视觉分支负责从配图中抽取用于判断任务的特征不负责理解图片内容。用 ImageNet 预训练模型来初始化然后在新闻数据集上微调。from transformers import AutoImageProcessor, AutoModelForImageClassification image_processor AutoImageProcessor.from_pretrained(google/vit-base-patch16-224) image_model AutoModelForImageClassification.from_pretrained( google/vit-base-patch16-224, num_labels128, ignore_mismatched_sizesTrue )逻辑说明ignore_mismatched_sizesTrue是必填项。因为原模型的分类头是 1000 类ImageNet改成 128 维特征后会维度不匹配不加这个参数会直接报错。改动分类头维度是为了让视觉特征在融合层之前降维避免进入融合层时特征维度过大。参数说明可以选用resnet50替代vit效果相似但 CPU 推理更快。视觉特征被组织成一个 128 维的特征向量经过 L2 归一化后再进入融合层用于消除亮度、对比度差异带来的特征偏移。2.4 多模态融合层为什么用 128 维而不是直接拼接特征融合层是多模态识别成败的关键之一。简单粗暴地把 2048 维图像特征和 5000 维文本特征拼接起来后续的分类器在处理这种不平衡维度时权重更新会严重偏向高维一侧导致训练速度下降最终准确率也会受影响。常见的做法是用一个低维对齐层把两边都压到同一个尺度再融合。class MultimodalFusion(nn.Module): def __init__(self, text_dim5000, image_dim128, fusion_dim128, num_classes2): super().__init__() self.text_proj nn.Linear(text_dim, fusion_dim) self.image_proj nn.Linear(image_dim, fusion_dim) self.classifier nn.Sequential( nn.Linear(fusion_dim * 2, 64), nn.ReLU(), nn.Dropout(0.3), nn.Linear(64, num_classes) ) def forward(self, text_vec, image_vec): text_h self.text_proj(text_vec) image_h self.image_proj(image_vec) fusion torch.cat([text_h, image_h], dim-1) return self.classifier(fusion)参数说明text_dim5000对应 TF-IDF 的max_features如果改了分词配置这里要同步改。image_dim128对应 VIT 特征维度如果换成 ResNet 的 2048 维这里要同步改。fusion_dim128是融合向量的维度不是越大越好超过 256 之后在小数据集上会开始过拟合。Dropout(0.3)在全连接层之间做正则化数据量低于 5 万条时0.3 比 0.5 更稳。融合后的特征向量长度固定为fusion_dim * 2 256接一个两层 MLP 输出二分类概率。文本特征在这个阶段会被完全压缩到 128 维这个降维过程对噪声也有抑制作用。2.5 双编码器训练把训练过程分成冻结、微调、联合三个阶段多模态识别的训练和普通分类任务不一样不能一开始就把所有参数都放开。常见做法是分三个阶段每个阶段负责不同层次的学习阶段一冻结图像编码器只训练融合层。让融合层先适应两种特征的统计分布这个阶段跑 5-10 个 epoch。如果一开始就放开图像编码器预训练权重会被少量标注数据带偏。阶段二解冻图像编码器用较低的学习率比如 2e-5微调。这时候融合层已经稳定反向传播的梯度在特征空间中会按预期方向流动训练过程才可控。阶段三联合微调文本向量器。TF-IDF 本身不参与梯度更新所以文本向量器不涉及反向传播。如果在文本侧选择 BERT 方案本阶段才需要解冻文本编码器。训练一个 epoch 的参考代码如下for batch in train_loader: text_ids, images, labels batch text_vec vectorizer.transform(text_ids) # 转成 TF-IDF 向量 text_vec torch.tensor(text_vec.toarray(), devicedevice) image_vec image_model(images).logits image_vec torch.nn.functional.normalize(image_vec, p2, dim-1) logits fusion_model(text_vec, image_vec) loss criterion(logits, labels) optimizer.zero_grad() loss.backward() optimizer.step()逻辑说明vectorizer.transform返回的是稀疏矩阵必须先.toarray()转成稠密张量才能输入nn.Linear。image_model(images).logits拿的是分类头的输出向量在这里它被当作图像特征使用而不是直接输出类别概率。normalize这一步是让图像特征在进入融合层前保持单位长度防止某些图片特征模长过大主导融合结果。参数说明optimizer用 AdamW冻结阶段学习率 1e-3解冻后整体降到 2e-5。同一份代码里同时存在两个学习率所以优化器要分成两个参数组。3. 构建多模态数据集把新闻文本与配图对齐排查数据层面的坑虚假新闻检测的数据集是整个项目里最麻烦的环节。公开的新闻数据集大多是纯文本多模态的数据集需要同时有新闻正文和配图还要有真实/虚假标签能直接下载的并不多。这个项目的数据通常以 CSV 加图片文件夹的形态存在拿到数据后要先做一次质量检查而不是直接扔进模型。3.1 数据质量检查先算出文本和图像样本的对齐率多模态数据最容易出问题的点在于对齐。配图和文本对不上多模态模型比单模态模型更脆弱。因为模型会尝试学习“文本描述 A 对应图片 B”的关系一旦对应关系是错的它会用这些错误的对应关系学到一套自洽的假规律在两个模态的信息本来就矛盾的真实样本上反而会失效。import pandas as pd from pathlib import Path df pd.read_csv(news_data.csv) img_root Path(images) df[has_img] df[image_id].apply(lambda x: (img_root / x).exists()) print(df.groupby(label)[[has_img, text_len]].mean()) # 检查文本与图片是否大致对齐按字符长度分布 df[text_len] df[text].str.len() mismatch df[(df[text_len] 50) (df[has_img] True)] print(f短文本有图样本数: {len(mismatch)})逻辑说明has_img列统计本地图片是否存在text_len按字符数粗筛文本是否过短。短文本加有图不算错误但如果占总量的比例超过 10%说明数据标注时可能把纯图片新闻也算进去了这种样本在训练时会把文本分支的信号冲淡。参数说明text_len 50这个阈值是针对英语新闻设置的中文新闻 50 个字以下很难承载完整信息可以调整到 30。如果数据集里全是视频封面帧images/下的文件命名要和image_id完全一致注意 Windows 系统里jpg和JPG会被视为不同文件。3.2 把 CSV 文本切分成带标签的 PyTorch Datasetfrom torch.utils.data import Dataset class NewsDataset(Dataset): def __init__(self, df, vectorizer, img_dir, processor): self.df df.reset_index(dropTrue) self.vectorizer vectorizer self.img_dir img_dir self.processor processor def __len__(self): return len(self.df) def __getitem__(self, idx): row self.df.iloc[idx] text_vec self.vectorizer.transform([row[clean_text]]) text_vec torch.tensor(text_vec.toarray(), dtypetorch.float32).squeeze(0) img_path self.img_dir / row[image_id] image Image.open(img_path).convert(RGB) pixels self.processor(image, return_tensorspt)[pixel_values].squeeze(0) label torch.tensor(row[label], dtypetorch.long) return {text_vec: text_vec, pixels: pixels, label: label}逻辑说明__getitem__返回一个字典而不是元组后面写训练循环时语义更清晰。每次取数据时都打开图片并做预处理数据量大时可以调整num_workers来并行加载。参数说明processor是 2.3 节里定义的AutoImageProcessorreturn_tensorspt控制输出格式。.squeeze(0)用来去掉 batch 维度因为单条数据必须是[C, H, W]形状而不是[1, C, H, W]否则模型会报 batch 维度不匹配的错误。vectorizer.transform每次返回稀疏矩阵转成稠密toarray()会导致内存占用偏高2 万条数据时还好20 万条时就要考虑在内存里换一种表示方式。图片文件缺失时Image.open会抛FileNotFoundError最稳妥的做法是直接丢弃缺失样本。3.3 标签分布检查与类别不平衡处理虚假新闻数据集有个常见问题伪造新闻占比通常在 30% 到 40% 之间。如果训练时不做平衡处理模型会把所有样本都预测为真实新闻准确率依然很高但实际毫无用处。label_dist df[label].value_counts(normalizeTrue) if label_dist.min() 0.3: print(警告: 类别不平衡精度指标不可靠改用 Macro-F1) from sklearn.metrics import classification_report print(classification_report(y_true, y_pred, target_names[real, fake]))逻辑说明classification_report会把 precision、recall、F1 分标签输出。做多模态识别的项目里只看 accuracy 不看 F1 几乎一定会翻车。在低召回率场景里真实新闻的准确率很高但假新闻几乎全漏这个报告里会看得一清二楚。参数说明如果确实存在不平衡问题最直接的解法是给CrossEntropyLoss设置weight参数。用torch.tensor([1.0, 2.0])这样的比例具体数值按训练集统计结果来填。更激进的做法是重采样但重采样配合多模态模型容易让文本和图像的组合分布失真所以一般先调 loss 权重不急着重采样。4. 多模态模型微调学习率、批大小和早停策略以及验证集对比结果模型架构确定之后进入到最消耗时间的训练环节。多模态识别落地时新手和熟手的差距往往体现在三个参数的设置上学习率、batch size 和早停策略。这三个参数单独调都不难但它们相互影响调参时要看组合效果。4.1 学习率先预热再衰减多模态模型最容易在第一个 epoch 就发散多模态模型里不同分支的收敛速度不一样文本分支通常比图像分支收敛快很多。一个过大的全局学习率会把图像分支的预训练权重破坏掉。常见做法是加一个 warmup 阶段头 3 个 epoch 让学习率从 0 线性升到目标值后面再用余弦退火降下来。from torch.optim.lr_scheduler import LinearLR, CosineAnnealingLR, SequentialLR warmup LinearLR(optimizer, start_factor0.1, end_factor1.0, total_iters3) anneal CosineAnnealingLR(optimizer, T_max12, eta_min1e-6) scheduler SequentialLR(optimizer, schedulers[warmup, anneal], milestones[3])逻辑说明start_factor0.1是让第一个 epoch 的学习率只有目标值的 10%到第 3 个 epoch 结束时升到目标值。CosineAnnealingLR的T_max12指从第 3 个 epoch 之后再过 12 个 epoch 降到最低点。这两个组合起来能把训练过程中的 loss 震荡压下去很多。参数说明milestones[3]表示第 3 个 epoch 结束后切到第二个调度器。如果训练轮数只有 6那T_max也要跟着改小否则余弦下降还没走完就提前结束了。4.2 batch size 和显卡显存限制下的最小配置多模态模型显存占用的大头是图像编码器。VIT Base 的输入是 224x224 的三通道图像单张大约占用 1.2 GB 显存含梯度batch size 4 时大约 5 GB 上下8GB 显存勉强能跑但几乎没法同时开大 batch 和做梯度累积。train_loader DataLoader( train_dataset, batch_size8, shuffleTrue, num_workers4, pin_memoryTrue )逻辑说明如果 8G 显存会 OOM内存溢出就把batch_size调成 4同时打开梯度累积用两步累积来等效一个 batch size 8 的更新。num_workers4让数据加载并行但如果__getitem__里做了大量预处理瓶颈仍在 CPU 上这时候pin_memoryTrue反而会让显存占用略微上升。参数说明shuffleTrue只用于训练集验证集和测试集必须设成False否则评估结果不稳定。如果 CPU 核数不足num_workers4有时反而更慢。一个常见判断方法是看训练日志里DataLoader的等待时间占比如果 GPU 利用率常驻低于 50%优先检查是加载慢还是模型小。4.3 早停策略和保存最优模型验证集 Macro-F1 连续没提升就停下多模态模型迭代次数不宜太多通常 15-20 个 epoch 就到了平台期。很多项目就是在这个阶段过度训练验证集 F1 在 0.87 附近徘徊训练集却已经冲到 0.95过拟合的特征就开始出现了。早停的代码单独抽出来写不依赖第三方库。best_f1 0.0 patience 4 bad_epochs 0 for epoch in range(max_epochs): train_loss train_one_epoch(...) val_f1 evaluate(val_loader, ...) if val_f1 best_f1: best_f1 val_f1 bad_epochs 0 torch.save({ fusion: fusion_model.state_dict(), image_encoder: image_model.state_dict(), optimizer: optimizer.state_dict(), }, best_model.pt) print(fepoch {epoch}: save, F1{val_f1:.4f}) else: bad_epochs 1 if bad_epochs patience: print(early stop) break逻辑说明patience4表示连续 4 个 epoch 的验证集 F1 没有刷新纪录就停止训练。best_model.pt不是整个模型对象而是各分支的state_dict。存optimizer.state_dict是为了支持后续从断点恢复训练虽然初版用不到但能省掉一个后悔药。参数说明max_epochs设 20理论上在这个范围内应该能触发早停。如果到第 20 个 epoch 还没触发说明验证集波动很大要检查是不是数据切分时没有stratify或者 batch size 太小导致梯度不稳定。4.4 对照实验单文本、单图像、多模态效果分别如何多模态识别项目必须有一个对照实验否则无法回答“多模态到底比单模态强在哪”这个问题。建立一个三列对比基准文本单独跑一个 LR逻辑回归图像单独跑一个微调后的分类头多模态跑 2.4 节的融合模型。下面是一个简化的记录表模型验证集 Macro-F1说明文本 TF-IDF LR0.83标题党检测的文本基线图像 VIT 特征 LR0.88仅靠配图特征的基线的补充多模态融合0.91文本图像融合层逻辑说明表格里的数字是典型值。在真实项目中单文本和单图像的差距通常很大取决于数据集的文本质量。如果单图像已经到 0.91而加上文本只有 0.90说明多模态融合层的设计有问题。首先要怀疑文本分支存在过拟合检查训练时的文本 loss 是否下降异常快。参数说明调参没有跑过对照组之前不能说某个改动起作用了。常见做法是每改一次超参就把三列指标记录下来比较后再决定下一步。这也是判断多模态融合是否有效的最直接方式如果融合模型的 F1 不高于两个单模态中的最优值说明模型结构或训练策略有问题。5. 多模态识别结果验证与诊断把这套真假分类器落到本地推理模型训练完只是第一步。虚假新闻检测在实际使用中最关心的不是整体准确率而是“它判断错了会怎样”。需要单独做的验证和诊断包括评估指标的分标签查看、推理时间统计以及把模型包装成一个简单的命令行工具。5.1 从保存的检查点恢复模型在测试集上输出分标签指标使用best_model.pt做推理前必须做一步model.eval()。这个操作会关闭 Dropout 和 BatchNorm 的训练行为否则推理结果每次都不一样排查时容易让人误以为模型不稳定实际上是从没切换过推理模式。def load_model(checkpoint_path): fusion_model MultimodalFusion(...) image_model AutoModelForImageClassification.from_pretrained( google/vit-base-patch16-224, num_labels128, ignore_mismatched_sizesTrue ) state torch.load(checkpoint_path, map_locationcpu) fusion_model.load_state_dict(state[fusion]) image_model.load_state_dict(state[image_encoder]) fusion_model.eval() image_model.eval() return fusion_model, image_model逻辑说明map_locationcpu保证在没有 GPU 的机器上也能加载检查点。load_state_dict必须和保存时的键保持一致如果保存的是{fusion: ...}加载时也要用state[fusion]。如果遇到尺寸不匹配的报错通常是因为重建模型时的num_labels和保存时不一致。参数说明torch.load在 PyTorch 2.0 以上的版本里对weights_only参数有默认值的变更。推荐显式写torch.load(checkpoint_path, map_locationcpu, weights_onlyTrue)避免加载时执行任意 Python 对象反序列化尤其在处理来源不明的权重文件时更稳妥。5.2 推理时间统计头一次跑通时单条新闻耗时多少可以接受虚假新闻检测在离线批处理场景中单条推理耗时达到几百毫秒到一两秒都算正常。但如果要在 web 服务里被高频调用就要压缩预处理和数据加载的时间。下面给一个统计多次推理耗时的模板import time def predict(news_text, img_path, vectorizer, processor, fusion_model, image_model): text_vec vectorizer.transform([news_text]).toarray() text_vec torch.tensor(text_vec, dtypetorch.float32) image Image.open(img_path).convert(RGB) pixels processor(image, return_tensorspt)[pixel_values] with torch.no_grad(): image_vec image_model(pixel_valuespixels).logits image_vec torch.nn.functional.normalize(image_vec, p2, dim-1) logits fusion_model(text_vec, image_vec) return torch.softmax(logits, dim-1).squeeze(0).tolist()逻辑说明torch.no_grad()的作用是让推理过程不保存中间激活值内存占用和耗时都会降下来。这段代码把整条推理链路串起来是部署前的最小实现。热点是vectorizer.transform和Image.open通常各自占 30% 以上的耗时和模型本身关系不大。参数说明如果要在 web 服务里调用建议提前把 TF-IDF 向量器序列化成文件不要每次推理都重新fit。用joblib.dump(vectorizer, vectorizer.joblib)存下来加载时用joblib.load能避免重复加载耗时。5.3 三个最容易在部署后翻车的问题现象原因解决推理结果每次不一样没有切换model.eval()在预测前显式调用eval()关闭 Dropout 等随机机制图片缺失直接抛异常__getitem__里没有判空统一抛FileNotFoundError在数据加载阶段直接丢弃该样本GPU 上训练正常切到 CPU 推理报错保存的是 CUDA 张量保存时用.cpu()把state_dict转成 CPU 张量逻辑说明这三条有一个共同点都是“训练环境正常、部署环境异常”的典型坑。第一类最隐蔽因为每次结果不同很难被察觉如果结果在真实/虚假之间跳动那基本上就是 eval 模式的问题。第二条在实际部署时几乎都会遇到因为漏下载图片、命名不一致等风险清单很长所以要预先想清楚策略。第三条发生在单机多卡或跨机器场景torch.save默认会把参数留在原设备上要用.cpu()收一下再存。5.4 附上一条可复现的最小调用示例import torch from PIL import Image model, image_model load_model(best_model.pt) text BREAKING: 科学家发现彻底治愈癌症的新方法 img_path images/test_001.jpg prob predict(text, img_path, vectorizer, processor, fusion_model, image_model) print(ffake_prob{prob[1]:.4f})逻辑说明这个示例如果跑出来的fake_prob接近 1说明文本特征和图像特征都指向“可疑”。如果fake_prob在 0.5 附近通常是文本太短或图片类别太泛需要回到 3.1 节重新检查数据对齐质量。参数说明示例里images/test_001.jpg要和news_data.csv中的image_id字段完全一致。假如数据里图片名是数字 ID而 CSV 里是img_001.jpg需要统一格式化。6. 多模态识别闭环优化从置信度阈值到可复用的检测工具模型调通之后的优化方向重点不在换个更大的模型而在把检测流程固定下来、把文档补全、把整个目录整理成可以交接给别人的一套方案。这一步做得好不好直接决定项目是一次性实验还是真正能用的工具。6.1 加一个“不确定判定”多模态识别中的拒识场景虚假新闻检测和一般分类有一点不一样它面对的是开放世界的真实输入不是训练集里的干净分布。新闻里可能有不存在的图片、被裁剪的异常比例、罕见语言这类输入不应该被硬分类成“真实”或“虚假”。处理办法是加一个简单的不确定判定逻辑当 softmax 的两个概率都低于阈值比如最大概率小于 0.7时返回“需要人工复核”。def predict_with_reject(news_text, img_path, threshold0.7): prob predict(news_text, img_path, ...) max_prob max(prob) if max_prob threshold: return {label: unknown, prob: max_prob} return {label: fake if prob[1] 0.5 else real, prob: max_prob}逻辑说明threshold0.7这个数值不是固定的要在验证集上画一个置信度分布再看分错样本主要落在哪些区间。如果数据集里假新闻和真新闻本身有重叠这个值要适当调低到 0.6。放进系统里之后这条分支可以把模型最“没把握”的样本交给人工判断而不是让模型硬猜。6.2 文档说明里的关键一页把模型报告、数据统计、复现命令写全整套源码包交付过几次之后我的经验是文档说明要能支撑从零复现。需要包含的内容大概有这几部分环境依赖Python 版本、库版本、目录结构说明、最小可运行命令、训练参数、评估指标。下面是一个文档模板的骨架# 最小可运行命令 python train.py --data news_data.csv --img_dir images --epochs 20 --patience 4 # 评估命令 python evaluate.py --checkpoint best_model.pt --test news_test.csv逻辑说明evaluate.py单独写一个脚本不要和训练脚本耦合在一起。训练脚本每次运行都会把 checkpoint 存到当前目录evaluate.py读取这个 checkpoint 输出分类报告。命令行的参数命名要稳定--data、--img_dir、--checkpoint这些不要换名字换一次各种自动化和交接脚本全得跟着改。6.3 我把这套方案收敛到可复用的四个习惯从零到一做完一遍之后对“基于 Python 的虚假新闻检测多模态识别”这个标题背后的落地路线有了比较完整的认识。以下几个习惯是我现在每做一个类似项目都会固定执行的第一每次跑实验之前先把数据切分、标签分布、文本长度分布记录到一个固定的调试笔记里。多模态项目里 80% 的调试时间和“数据不对齐”有关和数据本身的对齐情况写好后面排查能省一晚上的时间。翻过几次车之后你会发现大多数玄学问题最后都能追溯到数据准备阶段。第二每次模型结构或超参数变更都保留一份参数记录。训练日志里至少要有数据集规模、学习方法、batch size、训练集/验证集 Macro-F1、保存的模型路径。不记录这些三天后回来看这段代码就只剩黑匣子了。第三对“模型输出结果”始终保持怀疑。多模态模型在真实/虚假两类上都给出高概率时要去看样本本身的特征而不是继续调模型。模型输出的不确定边界区域是下一个版本数据扩充的重点。第四部署到本地服务时预处理的失败和推理的失败要分开记录日志。图片读取失败、文本为空、特征维度不匹配这三类错误不该出现在同一个日志文件里。分开后排查效率会高很多。虚假新闻检测的多模态识别做出来一个 0.91 F1 的模型不是终点关键是把判断边界、数据来源、模型局限讲清楚。文档说明和数据质量检查清单往往比模型权重本身更值钱。希望这篇文章里的代码和排查思路能帮你少走几趟弯路在真实数据上跑出一版可信的结果。本文还有配套的精品资源点击获取
返回列表