python打卡day46@浙大疏锦行

知识点回顾:

  1. 不同CNN层的特征图:不同通道的特征图
  2. 什么是注意力:注意力家族,类似于动物园,都是不同的模块,好不好试了才知道。
  3. 通道注意力:模型的定义和插入的位置
  4. 通道注意力后的特征图和热力图

内容参考

作业:

  1. 今日代码较多,理解逻辑即可
  2. 对比不同卷积层特征图可视化的结果(可选)

一、CNN特征图可视化实现

复制代码
import torch
import matplotlib.pyplot as plt

def visualize_feature_maps(model, input_tensor):
    # 注册钩子获取中间层输出
    features = []
    def hook(module, input, output):
        features.append(output.detach().cpu())
    
    # 选择不同卷积层观察
    target_layers = [
        model.layer1[0].conv1,
        model.layer2[0].conv1,
        model.layer3[0].conv1
    ]
    
    handles = []
    for layer in target_layers:
        handles.append(layer.register_forward_hook(hook))
    
    # 前向传播
    with torch.no_grad():
        _ = model(input_tensor.unsqueeze(0))
    
    # 移除钩子
    for handle in handles:
        handle.remove()
    
    # 可视化不同层特征图
    fig, axes = plt.subplots(len(target_layers), 5, figsize=(20, 10))
    for i, feat in enumerate(features):
        for j in range(5):  # 显示前5个通道
            axes[i,j].imshow(feat[0, j].numpy(), cmap='viridis')
            axes[i,j].axis('off')
    plt.show()

二、通道注意力模块示例

复制代码
class ChannelAttention(nn.Module):
    def __init__(self, in_channels, reduction=16):
        super().__init__()
        self.avg_pool = nn.AdaptiveAvgPool2d(1)
        self.max_pool = nn.AdaptiveMaxPool2d(1)
        
        self.fc = nn.Sequential(
            nn.Linear(in_channels, in_channels // reduction),
            nn.ReLU(),
            nn.Linear(in_channels // reduction, in_channels),
            nn.Sigmoid()
        )
    
    def forward(self, x):
        # ... existing code ...
        return x * attention_weights  # 应用注意力权重

三、热力图生成方法

复制代码
def generate_heatmap(model, input_img):
    # 前向传播获取梯度
    model.eval()
    input_img.requires_grad = True
    output = model(input_img)
    pred_class = output.argmax(dim=1).item()
    
    # 反向传播计算梯度
    model.zero_grad()
    output[0, pred_class].backward()
    
    # 获取最后一个卷积层的梯度
    gradients = model.layer4[1].conv2.weight.grad
    pooled_gradients = torch.mean(gradients, dim=[0,2,3])
    
    # 生成热力图
    activations = model.layer4[1].conv2.activations.detach()
    for i in range(activations.shape[1]):
        activations[:,i,:,:] *= pooled_gradients[i]
    heatmap = torch.mean(activations, dim=1).squeeze()
    
    return heatmap
相关推荐
卷毛的技术笔记1 小时前
告别硬编码!Spring AI Alibaba 实现 AI Agent 智能工具调用(Tool Calling)
java·人工智能·后端·python·spring·ai编程
编程大师哥1 小时前
匿名函数 lambda + 高阶函数
java·python·算法
isyangli_blog1 小时前
OpenDayLight (Carbon 版本) 启动与组件安装
开发语言·php
vb2008111 小时前
FastAPI APIRouter
开发语言·python
Benszen1 小时前
KVM虚拟化解决方案
开发语言·perl
会编程的土豆1 小时前
Go 语言反射(Reflection)详解
开发语言·后端·golang
東雪木1 小时前
多线程与并发编程 专属复习笔记
java·开发语言·笔记·java面试
adrninistrat0r1 小时前
Java调用链MCP分析工具
java·python·ai编程
杨充2 小时前
1.3 浮点型数据设计灵魂
开发语言·python·算法
噜噜噜阿鲁~2 小时前
python学习笔记 | 11.3、面向对象高级编程-多重继承
java·开发语言