不仅仅是标签:使用 ResNet-50 和 Explainable AI(Grad-CAM)构建皮肤病变分类器

发布: (2026年2月5日 GMT+8 08:50)
6 分钟阅读
原文: Dev.to

Source: Dev.to

Beck_Moulton

介绍

你是否曾在观看医学 AI 演示时想过,“当然,它说是皮疹,但模型到底在看什么?”计算机视觉医学 AI 领域,黑箱 问题不仅是技术障碍——更是信任障碍。

在构建皮肤病变筛查工具时,单纯的百分比得分并不足够。要打造真正有用的工具,我们需要 可解释 AI(XAI)。在本指南中,我们将:

  • 使用 PyTorchFastAI 构建深度学习流水线,以对皮肤疾病进行分类。
  • 实现 Grad‑CAM,生成热图,突出显示哪些特征(纹理、颜色、边界)影响了模型的决策。

无论你对 深度学习、健康科技感兴趣,还是仅仅想让你的模型更透明,本教程都涵盖了完整的工程实现。

架构

我们的系统遵循经典的客户端‑服务器模型,并添加了可解释性层。我们使用经过微调的ResNet‑50进行推理,并使用 React Native 前端提供用户体验。

graph TD
    A[User Takes Photo] --> B(React Native App)
    B --> C{FastAPI Backend}
    C --> D[ResNet‑50 Classifier]
    D --> E[Inference Result]
    D --> F[Grad‑CAM Hook]
    F --> G[Heatmap Generation]
    G --> H[Overlay Image]
    H --> I[Result + Visualization]
    E --> I
    I --> B

前置条件

要求细节
FastAI / PyTorch模型训练和微调
Grad‑CAM从最后的卷积层提取梯度
React Native跨平台移动界面
Dataset例如 HAM10000(Human‑Against‑Machine,1 万张训练图像)

第 1 步:使用 FastAI 微调 ResNet‑50

FastAI 使 迁移学习 变得极其高效。下面是一段最小化脚本,用于在皮肤病变图像上微调预训练的 ResNet‑50。

from fastai.vision.all import *

# Load data – assumes images are organized in folders by label
path = Path('./skin_lesion_data')
dls = ImageDataLoaders.from_folder(
    path,
    valid_pct=0.2,
    item_tfms=Resize(224)
)

# Initialize Learner with ResNet‑50
learn = vision_learner(dls, resnet50, metrics=accuracy)

# Find optimal learning rate and train
learn.fine_tune(5, base_lr=3e-3)

# Export for production
learn.export('skin_classifier.pkl')

第2步:实现 Grad‑CAM 以进行可解释性

Grad‑CAM(Gradient‑weighted Class Activation Mapping)利用流入最后一个卷积层的梯度来生成定位图。

import torch
import numpy as np

class GradCAM:
    def __init__(self, model, target_layer):
        self.model = model
        self.target_layer = target_layer
        self.gradients = None
        self.activations = None

        # Register hooks
        self.target_layer.register_forward_hook(self._save_activation)
        self.target_layer.register_full_backward_hook(self._save_gradient)

    def _save_activation(self, module, input, output):
        self.activations = output

    def _save_gradient(self, module, grad_input, grad_output):
        self.gradients = grad_output[0]

    def generate_heatmap(self, input_tensor, category_idx):
        # Forward pass
        output = self.model(input_tensor)
        self.model.zero_grad()

        # Backward pass for the specific category
        loss = output[0, category_idx]
        loss.backward()

        # Weight the activations by the gradients
        weights = torch.mean(self.gradients, dim=(2, 3), keepdim=True)
        heatmap = torch.sum(weights * self.activations, dim=1).squeeze()

        # ReLU and normalize
        heatmap = np.maximum(heatmap.detach().cpu().numpy(), 0)
        heatmap /= np.max(heatmap)
        return heatmap

注意: 将此功能集成到你的 API 中,以同时返回诊断结果(例如 “Melanocytic nevi”)和可视化热图图像。

扩展到生产环境

虽然原型是一个很好的起点,但部署医疗级 AI 需要:

  • 严谨的测试与验证
  • 数据隐私合规(HIPAA、GDPR 等)
  • 稳健的 MLOps 流水线

欲获取生产就绪的示例、高级计算机视觉模式以及 AI 安全的深入探讨,请查看 WellAlly Tech Blog 的技术资源。

第3步:前端可视化(React Native)

在移动端,我们显示原始图像,并允许用户(或临床医生)切换热图叠加层。

import React, { useState } from 'react';
import { View, Image, Button, Text } from 'react-native';

const ResultScreen = ({ route }) => {
  const { originalUri, heatmapUri, prediction } = route.params;
  const [showHeatmap, setShowHeatmap] = useState(false);

  return (
    <View>
      <Text>Result: {prediction}</Text>
      <Image source={{ uri: showHeatmap ? heatmapUri : originalUri }} style={{ width: 300, height: 300 }} />
      <Button
        title={showHeatmap ? "Hide Heatmap" : "Show Heatmap"}
        onPress={() => setShowHeatmap(!showHeatmap)}
      />
    </View>
  );
};

export default ResultScreen;
import React, { useState } from "react";
import { View, Switch, Text } from "react-native";

const HeatmapToggle = () => {
  const [showHeatmap, setShowHeatmap] = useState(false);

  return (
    <View>
      <Text>Show Grad‑CAM Heatmap (Logic)</Text>
      <Switch
        value={showHeatmap}
        onValueChange={() => setShowHeatmap(!showHeatmap)}
      />
    </View>
  );
};

export default HeatmapToggle;

全屏控制

  • 进入全屏模式
  • 退出全屏模式

结论:弥合差距

通过将 FastAI 用于快速开发与 Grad‑CAM 用于透明性相结合,我们将一个简单的分类器转变为强大的诊断辅助工具。该设置不仅提供答案,还提供原因

关键要点

  • 迁移学习(ResNet‑50)可节省数周的训练时间。
  • 在医学等高风险领域,可解释性是不可妥协的。
  • 混合技术栈(Python 后端 + React Native 前端)为 AI 产品提供了最佳的开发者体验。

你对 AI 可解释性有什么看法?如果 AI 能通过热图向你展示它的“思考过程”,你会更信任它吗?欢迎在下方评论区讨论!

如果你喜欢本教程,别忘了 ❤️ 和 🔖!想了解更多高级 AI 实施策略,请访问 WellAlly Blog

Back to Blog

相关文章

阅读更多 »

当 AI 给你一巴掌

当 AI 给你当头一棒:在 Adama 中调试 Claude 生成的代码。你是否曾让 AI “vibe‑code” 一个复杂功能,却花了数小时调试细微的 bug……