新闻详情

新闻详情

首页 / 资讯中心 / 详情

ResNet 到底在看哪里?我用码道做了一个 Grad-CAM 可视化实验

发布时间:2026/10/1 19:54:07来源:尧图网络
ResNet 到底在看哪里?我用码道做了一个 Grad-CAM 可视化实验
项目地址cnn-mnist-playground:基于 PyTorch 的 CNN 手写数字识别与可视化实验项目 - AtomGit前面几篇文章里我已经在同一个cnn-mnist-playground项目中完成了 CNN 手写数字识别、Conv1 / Conv2 Feature Map 可视化以及 CNN 与 MLP 的对比实验。做到这里以后我又有了一个新的问题模型虽然能把数字识别出来但它在做出这个分类结果时到底更关注图像中的哪些区域所以这一次我继续使用码道 Agent在原项目基础上加入一个轻量级 ResNet并实现 Grad-CAM 可视化让分类结果背后的空间响应能够直接显示出来。一、继续在原项目上加入 ResNet这次我没有重新开一个仓库而是继续在原来的项目上增量开发。现在整个实验路线已经变成CNN 手写数字识别→ Feature Map 可视化→ CNN vs MLP→ ResNet→ Grad-CAM这样做的好处是输入任务始终都是 MNIST只改变网络结构和分析方式更方便观察不同方法之间的差异。这一次用的也不是直接照搬 torchvision 的原版 ResNet18而是根据 MNIST 的28×28单通道输入设计了一个轻量 ResNet。模型输入为1×28×28最终输出 10 个类别对应数字 09。网络中使用了多个残差块并逐步把空间尺寸从28×28降到14×14最后降到7×7再通过 Global Average Pooling 和全连接层完成分类。最终模型真实参数量为174,970二、本地真实训练测试准确率 99.14%代码完成以后我还是按照之前的方式不让 Agent 去假设训练结果而是在自己的 PyTorch 环境中进行真实训练。训练命令python -m scripts.train_resnet --epochs 5训练完成后模型权重保存到app/weights/mnist_resnet.pth最终 ResNet 的真实测试集准确率为99.14%而上一篇 CNN vs MLP 实验中MLP 的真实测试准确率为97.92%在当前这套 MNIST 实验配置下轻量 ResNet 得到了更高的测试准确率。当然这只能说明当前实验结果不能简单得出“ResNet 在所有情况下都一定优于 MLP”的结论。三、Grad-CAM 到底在做什么Grad-CAM 的全称是Gradient-weighted Class Activation Mapping它想解决的问题并不是“模型预测了什么”而是对于当前这个类别卷积特征图中的哪些空间区域对输出贡献相对更大它的大致过程是先进行一次正常的前向传播得到分类结果然后针对目标类别进行反向传播计算目标类别得分对最后卷积层 Feature Map 的梯度。这些梯度经过空间平均后可以得到每个通道对应的权重再利用这些权重对 Feature Map 加权求和经过 ReLU 和归一化以后就得到了最终的 Grad-CAM。这次项目选择的 Target Layer 是stage3[-1].conv2也就是最后一个残差阶段中最后一个 BasicBlock 的第二个卷积层。为了获取真实的 Feature Map 和 Gradient我在实现中使用了 PyTorch Hooktarget_layer.register_forward_hook( self._save_activation)target_layer.register_full_backward_hook( self._save_gradient)也就是说页面上看到的热力图不是随机生成的图片而是真正根据当前输入、当前模型和当前目标类别实时计算出来的。四、最终页面效果前端新增了一个独立的ResNet Grad-CAM 可视化区域。页面中可以直接看到模型名称MnistResNet输入尺寸1×28×28参数量174,970测试准确率99.14%以及 Grad-CAM Target Layerstage3[-1].conv2。手写一个数字以后点击“生成 Grad-CAM”页面就会同时显示预测类别、置信度、Target Class、原始输入、Grad-CAM 热力图和 Overlay 叠加图。整个流程已经完整打通手写数字→ ResNet 推理→ 得到预测类别→ 反向传播→ Grad-CAM→ Heatmap→ Overlay五、真实案例数字 0第一个测试是手写数字0。最终结果Prediction0 Confidence95.18% Target Class0 Target Layerstage3[-1].conv2从热力图中可以看到高响应区域主要分布在数字笔画及其内部邻近区域。Overlay 把热力图直接叠加到了原始输入上这样比单独看一张 Heatmap 更容易观察空间响应与数字结构之间的位置关系。不过这里需要特别注意Grad-CAM 的高响应区域不能简单理解成“模型真正看到了这里”。更加准确的理解应该是在当前输入和当前目标类别下这些空间区域对类别输出的贡献相对更大。六、再测试数字 8 和 9随后我又分别手写了数字8和9。数字8的结果为Prediction8 Confidence99.75%从当前结果来看数字 8 的高响应区域主要集中在中上部以及两个环的连接附近。数字9的结果为Prediction9 Confidence99.91%数字 9 的高响应区域则更多集中在上方闭环以及中部附近。三个真实案例分别为数字 0置信度 95.18%数字 8置信度 99.75%数字 9置信度 99.91%。不同输入产生的 Grad-CAM 空间分布明显不同这也是这次实验最直观的地方。七、真正运行以后发现了一个 Bug7×7 对不上 28×28这次项目在真实运行 pytest 的时候还发现了一个很典型的问题。最开始执行pytest tests/test_resnet.py tests/test_gradcam.py -vResNet 本身的测试基本正常但 Grad-CAM 出现了多个失败。继续看 Traceback 后发现实际上核心问题只有一个GradCAMError: cam 与 base_image 形状不一致: (7, 7) vs (28, 28)原因也比较直接。原始 MNIST 图片是28×28但是经过 ResNet 的多次下采样后最后卷积层已经变成7×7所以从这个卷积层得到的原始 Grad-CAM 自然也是7×7。而 Overlay 需要把热力图和原始图像逐像素叠加7×7和28×28显然不能直接进行计算。八、解决方法先进行空间尺寸对齐这个问题不能简单地通过删除 shape 检查解决。因为即使不报错两个不同尺寸的数组依然无法正常进行 Overlay。最后采用的处理流程是Grad-CAM 7×7 ↓ Bilinear Resize ↓ 28×28 ↓ 与原始输入 Overlay ↓ 28×28 ↓ 显示时放大 ↓ 224×224核心代码类似if cam.shape ! base.shape: cam np.asarray( Image.fromarray(cam, modeF).resize( ( int(base.shape[1]), int(base.shape[0]) ), resampleImage.BILINEAR, ), dtypenp.float32, )这样原始 Grad-CAM 依然来自真实的7×7特征空间只是在进行 Overlay 前把它插值到和原始 MNIST 图像一致的28×28。最后放大到224×224只是为了让网页显示更加清楚。九、修复以后100 个专项测试全部通过修复尺寸问题以后我重新运行pytest tests/test_resnet.py tests/test_gradcam.py -v最终得到100 passed, 2 warnings in 3.94s这说明 ResNet 和 Grad-CAM 相关的模型结构、API、Heatmap、Overlay、空白输入以及异常处理等测试都已经正常。十、完整回归测试192 Passed因为这一次是在原来的项目上继续增加功能所以仅仅保证 Grad-CAM 能运行还不够。还要确认原来的 CNN、MLP、Feature Map、CNN vs MLP 和 API 没有因为新功能被破坏。于是最后重新运行整个测试集pytest -v最终结果192 passed, 2 warnings in 6.84s到这里ResNet Grad-CAM 的整个功能链条才算真正完成。相比“页面看起来能运行”我觉得这种完整回归测试更重要因为它可以确认新增功能没有破坏前面的实验。总结这一次在原来的 MNIST 实验平台上继续加入了轻量 ResNet 和 Grad-CAM。最终得到的真实结果是ResNet 参数量174,970测试准确率99.14%数字 0 的预测置信度95.18%数字 8 为99.75%数字 9 为99.91%ResNet Grad-CAM 专项测试100 passed完整项目回归测试192 passed。相比单纯看到一个分类结果我觉得 Grad-CAM 更有意思的地方是我们终于可以观察当前分类结果对应的空间响应主要分布在哪里。当然Grad-CAM 仍然不是完整的模型因果解释它更适合作为一种辅助观察神经网络决策过程的方法。现在这条实验路线已经做到CNN→ Feature Map→ CNN vs MLP→ ResNet→ Grad-CAM下一步准备继续进入目标检测开始做YOLO。项目地址cnn-mnist-playground:基于 PyTorch 的 CNN 手写数字识别与可视化实验项目 - AtomGit
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

MetaERP 总账里“实时汇率转换”不是界面上算个乘法那么简单,而是 汇率主数据 + 汇率类型 + 凭证上下文 + 前端联动 + 后端防篡改​ 五件事串起来。下面按“用户看到什么 / 系统怎么算 / 2026/10/1 19:54:07

MetaERP 总账里“实时汇率转换”不是界面上算个乘法那么简单,而是 汇率主数据 + 汇率类型 + 凭证上下文 + 前端联动 + 后端防篡改​ 五件事串起来。下面按“用户看到什么 / 系统怎么算 /

MetaERP 总账里“实时汇率转换”不是界面上算个乘法那么简单,而是 汇率主数据 汇率类型 凭证上下文 前端联动 后端防篡改​ 五件事串起来。下面按“用户看到什么 / 系统怎么算 / 后台怎么管”讲。一、凭证界面上用户看到什么录入外币凭证时,凭证头/行…

阅读更多 →
2026 企业 AI 办公工具选型指南:从评估框架到产品盘点 2026/9/30 17:06:43

2026 企业 AI 办公工具选型指南:从评估框架到产品盘点

一、企业选AI办公工具,为什么不能只看功能列表 不少企业在启动AI办公工具调研时,第一反应是拉一张长长的功能对比表,把不同产品的按钮数量、支持的文件格式、内置的AI能力项逐一罗列打分,最后选出得分最高的产品上线。但这类选型的…

阅读更多 →
老房翻新中石膏线接缝开裂的成因分析与防裂工艺要点 2026/10/1 19:54:07

老房翻新中石膏线接缝开裂的成因分析与防裂工艺要点

在老房翻新工程中,石膏线安装属于典型的"面子工程"。它造价不高、工期不长,却直接影响顶面与墙角的视觉收口效果。实际使用中,不少翻新完成一两年的房子,石膏线接缝处、阴角对接处会陆续出现发丝裂缝,严重时…

阅读更多 →

最新相关资讯

Claude Code 换模型后请求失败?检查 Base URL 与 Key 配置 2026/10/1 19:54:05

Claude Code 换模型后请求失败?检查 Base URL 与 Key 配置

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
如何防止跨站WebSocket劫持?ASCILINE的Origin校验+静态文件白名单安全设计解析 2026/10/1 19:54:04

如何防止跨站WebSocket劫持?ASCILINE的Origin校验+静态文件白名单安全设计解析

如何防止跨站WebSocket劫持?ASCILINE的Origin校验静态文件白名单安全设计解析 【免费下载链接】ASCILINE A high-performance ASCII video rendering engine featuring real-time WebSocket binary streaming and an isolated compiler for serverless static gener…

阅读更多 →
算法复杂度分析:O与θ到底怎么选?一文讲透符号边界 2026/10/1 19:54:04

算法复杂度分析:O与θ到底怎么选?一文讲透符号边界

“算法复杂度分析”这几个字,大概是我做技术这些年里被问得最多的一类话题。不管是带新人、做代码评审,还是自己设计批量任务方案,最后都会被同一个问题卡住:这个算法,数据规模翻个十倍,还扛得住吗&#xf…

阅读更多 →
Loop Engineering(循环工程):用 TaoToken 统一 Key 打通多模型循环调用链路 2026/10/1 19:54:04

Loop Engineering(循环工程):用 TaoToken 统一 Key 打通多模型循环调用链路

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
LeetCode 1680:二进制拼接的位运算递推与取模溢出实战解析 2026/10/1 19:54:03

LeetCode 1680:二进制拼接的位运算递推与取模溢出实战解析

刷LeetCode刷到1680题的时候,我第一反应是:这不就是把1到n的二进制串拼起来,转成十进制,再取个模吗?字符串拼接、进制转换、取模,三步走完,完事。直到我在本地把暴力版和位运算版分别跑了一遍&a…

阅读更多 →
工程车辆目标检测数据集实战:YOLOv8训练与避坑指南 2026/10/1 19:53:56

工程车辆目标检测数据集实战:YOLOv8训练与避坑指南

简介:这份工程车辆目标检测数据集面向建筑工地智能监控、智能交通与自动驾驶环境感知等方向的算法开发者与高校研究者,聚焦混凝土搅拌车、自卸卡车、挖掘机三类常见工程车辆的识别需求。资源包共902个文件,以450张JPEG实景图片和450个YOLO格式…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉