news 2026/5/19 11:22:41

DAY42 Grad-Cam和Hook函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DAY42 Grad-Cam和Hook函数

@浙大疏锦行

importtorchimporttorch.nnasnnimporttorch.nn.functionalasFimporttorchvisionimporttorchvision.transformsastransformsimportnumpyasnpimportmatplotlib.pyplotaspltfromPILimportImage torch.manual_seed(42)np.random.seed(42)transform=transforms.Compose([transforms.ToTensor(),transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])testset=torchvision.datasets.CIFAR10(root='./data',train=False,download=True,transform=transform)classes=('飞机','汽车','鸟','猫','鹿','狗','青蛙','马','船','卡车')classSimpleCNN(nn.Module):def__init__(self):super(SimpleCNN,self).__init__()self.conv1=nn.Conv2d(3,32,kernel_size=3,padding=1)self.conv2=nn.Conv2d(32,64,kernel_size=3,padding=1)self.conv3=nn.Conv2d(64,128,kernel_size=3,padding=1)self.pool=nn.MaxPool2d(2,2)self.fc1=nn.Linear(128*4*4,512)self.fc2=nn.Linear(512,10)defforward(self,x):x=self.pool(F.relu(self.conv1(x)))x=self.pool(F.relu(self.conv2(x)))x=self.pool(F.relu(self.conv3(x)))x=x.view(-1,128*4*4)x=F.relu(self.fc1(x))x=self.fc2(x)returnx# 初始化模型model=SimpleCNN()print("模型已创建")device=torch.device("cuda:0"iftorch.cuda.is_available()else"cpu")model=model.to(device)deftrain_model(model,epochs=1):trainset=torchvision.datasets.CIFAR10(root='./data',train=True,download=True,transform=transform)trainloader=torch.utils.data.DataLoader(trainset,batch_size=64,shuffle=True,num_workers=2)criterion=nn.CrossEntropyLoss()optimizer=torch.optim.Adam(model.parameters(),lr=0.001)forepochinrange(epochs):running_loss=0.0fori,datainenumerate(trainloader,0):inputs,labels=data inputs,labels=inputs.to(device),labels.to(device)optimizer.zero_grad()outputs=model(inputs)loss=criterion(outputs,labels)loss.backward()optimizer.step()running_loss+=loss.item()ifi%100==99:print(f'[{epoch+1},{i+1}] 损失:{running_loss/100:.3f}')running_loss=0.0print("训练完成")try:model.load_state_dict(torch.load('cifar10_cnn.pth'))print("已加载预训练模型")except:print("无法加载预训练模型,使用未训练模型或训练新模型")train_model(model,epochs=1)torch.save(model.state_dict(),'cifar10_cnn.pth')model.eval()classGradCAM:def__init__(self,model,target_layer):self.model=model self.target_layer=target_layer self.gradients=Noneself.activations=Noneself.register_hooks()defregister_hooks(self):defforward_hook(module,input,output):self.activations=output.detach()defbackward_hook(module,grad_input,grad_output):self.gradients=grad_output[0].detach()self.target_layer.register_forward_hook(forward_hook)self.target_layer.register_backward_hook(backward_hook)defgenerate_cam(self,input_image,target_class=None):model_output=self.model(input_image)iftarget_classisNone:target_class=torch.argmax(model_output,dim=1).item()self.model.zero_grad()one_hot=torch.zeros_like(model_output)one_hot[0,target_class]=1model_output.backward(gradient=one_hot)gradients=self.gradients activations=self.activations weights=torch.mean(gradients,dim=(2,3),keepdim=True)cam=torch.sum(weights*activations,dim=1,keepdim=True)cam=F.relu(cam)cam=F.interpolate(cam,size=(32,32),mode='bilinear',align_corners=False)cam=cam-cam.min()cam=cam/cam.max()ifcam.max()>0elsecamreturncam.cpu().squeeze().numpy(),target_class

importwarnings warnings.filterwarnings("ignore")importmatplotlib.pyplotasplt plt.rcParams["font.family"]=["SimHei"]plt.rcParams['axes.unicode_minus']=Falseidx=102image,label=testset[idx]print(f"选择的图像类别:{classes[label]}")deftensor_to_np(tensor):img=tensor.cpu().numpy().transpose(1,2,0)mean=np.array([0.5,0.5,0.5])std=np.array([0.5,0.5,0.5])img=std*img+mean img=np.clip(img,0,1)returnimg input_tensor=image.unsqueeze(0).to(device)grad_cam=GradCAM(model,model.conv3)heatmap,pred_class=grad_cam.generate_cam(input_tensor)plt.figure(figsize=(12,4))plt.subplot(1,3,1)plt.imshow(tensor_to_np(image))plt.title(f"原始图像:{classes[label]}")plt.axis('off')plt.subplot(1,3,2)plt.imshow(heatmap,cmap='jet')plt.title(f"Grad-CAM热力图:{classes[pred_class]}")plt.axis('off')plt.subplot(1,3,3)img=tensor_to_np(image)heatmap_resized=np.uint8(255*heatmap)heatmap_colored=plt.cm.jet(heatmap_resized)[:,:,:3]superimposed_img=heatmap_colored*0.4+img*0.6plt.imshow(superimposed_img)plt.title("叠加热力图")plt.axis('off')plt.tight_layout()plt.savefig('grad_cam_result.png')plt.show()

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 19:21:00

OBS面部追踪插件终极指南:打造专业直播画面的5个关键步骤

OBS面部追踪插件终极指南:打造专业直播画面的5个关键步骤 【免费下载链接】obs-face-tracker Face tracking plugin for OBS Studio 项目地址: https://gitcode.com/gh_mirrors/ob/obs-face-tracker OBS面部追踪插件是专为OBS Studio设计的实时面部检测工具&…

作者头像 李华
网站建设 2026/5/11 23:28:06

无线数据通信技术【1.5】

2.5.2 多普勒频移与多普勒衰落当运动的物体达到一定的速度时(如急速行使的汽车、 超音速飞机、 人造卫星在发射等),固定点接收到的从运动体发来的载波频率将随物体运动速度的不同产生不同的频移,导致信号频率扩展,通常…

作者头像 李华
网站建设 2026/5/17 6:34:54

Infinigen完全攻略:从零构建程序化世界的7个关键步骤

Infinigen完全攻略:从零构建程序化世界的7个关键步骤 【免费下载链接】infinigen Infinite Photorealistic Worlds using Procedural Generation 项目地址: https://gitcode.com/gh_mirrors/in/infinigen Infinigen是一款革命性的开源程序化世界生成工具&…

作者头像 李华
网站建设 2026/5/13 17:24:48

告别串口噩梦:打造工业现场的 Modbus 智能通信中枢

摘要:在工业物联网(IIoT)的升级改造中,工程师们常面临一个棘手的“时空错位”:一边是支持高并发、云原生的现代化 SCADA/MES 系统,另一边是躺在控制柜里主要靠串口通信的“古董”设备。如何让 TCP/IP 网络与…

作者头像 李华
网站建设 2026/5/18 20:37:51

空洞骑士模组管理器Scarab:从零开始的完整使用手册

空洞骑士模组管理器Scarab:从零开始的完整使用手册 【免费下载链接】Scarab An installer for Hollow Knight mods written in Avalonia. 项目地址: https://gitcode.com/gh_mirrors/sc/Scarab 还在为空洞骑士模组安装的繁琐步骤而头疼吗?Scarab模…

作者头像 李华
网站建设 2026/5/12 22:50:29

Win11Debloat终极指南:让你的Windows系统飞起来

Win11Debloat终极指南:让你的Windows系统飞起来 【免费下载链接】Win11Debloat 一个简单的PowerShell脚本,用于从Windows中移除预装的无用软件,禁用遥测,从Windows搜索中移除Bing,以及执行各种其他更改以简化和改善你的…

作者头像 李华