import torch
import cv2
import numpy as np
import matplotlib.pyplot as plt
from torchvision.models import *
from torchvision.transforms import ToTensor, Resize, Compose, Normalize
import glob
import PIL.Image
import os
from collections import OrderedDict
from IPython.display import Image
from matplotlib.animation import FuncAnimation
import sys
from efficientnet_pytorch import EfficientNet
# 设置中文字体显示
plt.rcParams["font.family"] = ["SimHei", "WenQuanYi Micro Hei", "Heiti TC"]
# 加载本地可视化库
sys.path.append(r"C:/Users/lenovo/Desktop/生物医学图像处理/final project/A-journey-into-Convolutional-Neural-Network-visualization--master")
from visualisation.core.utils import device, image_net_preprocessing, image_net_postprocessing, tensor2cam
from visualisation.core import GradCam
# 加载EfficientNet模型
def efficientnet(model_name='efficientnet-b0'):
return EfficientNet.from_pretrained(model_name).to(device)
# 加载测试图像
max_img = 5
path = r"C:/Users/lenovo/Desktop/生物医学图像处理/final project/bone_age"
interesting_categories = ['better'] # 选择三张效果好的X光片为例
images = []
category_labels = []
for category_name in interesting_categories:
image_paths = glob.glob(f'{path}/{category_name}/*')
if not image_paths:
print(f"警告: 在类别 {category_name} 中未找到图像")
continue
category_images = list(map(lambda x: PIL.Image.open(x), image_paths[:max_img]))
images.extend(category_images)
category_labels.extend([f"类别{category_name}"for _ in range(len(category_images))])
# 图像预处理
transform = Compose([
Resize((224, 224)),
ToTensor(),
Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])
inputs = [transform(x).unsqueeze(0) for x in images] # 添加batch维度
inputs = [i.to(device) for i in inputs]
# 定义要比较的模型
model_instances = [
alexnet,
densenet121,
resnet18,
resnet50,
lambda pretrained: efficientnet(model_name='efficientnet-b0'),
lambda pretrained: efficientnet(model_name='efficientnet-b2')
]
model_names = [m.__name__ for m in model_instances]
model_names[-2], model_names[-1] = 'EB0', 'EB2'
# 调整图像尺寸用于显示
display_images = list(map(lambda x: cv2.resize(np.array(x), (224, 224)), images))
# 对每个模型执行Grad-CAM
model_outs = OrderedDict()
for name, model in zip(model_names, model_instances):
module = model(pretrained=True).to(device)
module.eval()
vis = GradCam(module, device)
print(f"正在处理 {name} 模型...")
# 生成Grad-CAM结果
model_outs[name] = list(map(
lambda x: tensor2cam(vis(x, None, postprocessing=image_net_postprocessing)[0]),
inputs
))
del module
torch.cuda.empty_cache() # 释放GPU内存
# 创建输出目录
output_path = r'C:/Users/lenovo\Desktop/生物医学图像处理/final project/gradcam_comparisons'
os.makedirs(output_path, exist_ok=True)
# 为每张图像创建模型比较图
for img_idx, (orig_img, label) in enumerate(zip(display_images, category_labels)):
plt.figure(figsize=(16, 12))
# 计算子图布局: 1行(原始图像+模型数)列
n_models = len(model_names)
cols = n_models + 1 # 原始图像 + 所有模型
# 显示原始图像
plt.subplot(1, cols, 1)
plt.imshow(orig_img)
plt.title(f"{label}\n原始图像", fontsize=10)
plt.axis('off')
# 为每个模型显示Grad-CAM
for model_idx, model_name in enumerate(model_names):
grad_cam = model_outs[model_name][img_idx]
# 将热力图叠加到原始图像上
heatmap = cv2.applyColorMap(grad_cam, cv2.COLORMAP_JET)
superimposed_img = heatmap * 0.5 + orig_img * 0.5
# 显示叠加后的图像
plt.subplot(1, cols, model_idx + 2)
plt.imshow(superimposed_img)
plt.title(f"{model_name} Grad-CAM", fontsize=10)
plt.axis('off')
# 调整布局并保存
plt.tight_layout()
plt.subplots_adjust(top=0.9)
plt.suptitle(f"不同模型的Grad-CAM比较 (图像 {img_idx+1}/{len(images)})", fontsize=16)
# 保存图像
output_path = os.path.join(output_dir, f"gradcam_comparison_img{img_idx+1}.png")
plt.savefig(output_path, bbox_inches='tight', dpi=150)
plt.close()
print(f"已保存图像比较结果到: {output_path}")
print("所有图像比较结果已保存!")
依据你的修改意见,对我的代码形成具体的代码修改意见