知識點回顧:
- 不同CNN層的特征圖:不同通道的特征圖
- 什么是注意力:注意力家族,類似于動物園,都是不同的模塊,好不好試了才知道。
- 通道注意力:模型的定義和插入的位置
- 通道注意力后的特征圖和熱力圖
內容參考
作業:
- 今日代碼較多,理解邏輯即可
- 對比不同卷積層特征圖可視化的結果(可選)
一、CNN特征圖可視化實現
import torch
import matplotlib.pyplot as pltdef 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 = Trueoutput = model(input_img)pred_class = output.argmax(dim=1).item()# 反向傳播計算梯度model.zero_grad()output[0, pred_class].backward()# 獲取最后一個卷積層的梯度gradients = model.layer4[1].conv2.weight.gradpooled_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