利用Cam对Hopenet网络模型进行可视化
利用cam对论文中的模型中间层进行可视化操作,方面观察模型的注意点在哪。
需要注意的地方是,观察模型的主干网络,与 forword 层存在几个输出,若存在多个输出,
则改为一个
import os
import sys
import time
import cv2
import torch
import utils
import hopenet
import argparse
import torchvision
import torch.nn.functional as F
import torch.backends.cudnn as cudnn
import numpy as npfrom PIL import Image
from torchvision import transforms
from torch.autograd import Variable
from pytorch_grad_cam import GradCAM, ScoreCAM, GradCAMPlusPlus
from pytorch_grad_cam.utils.image import preprocess_image, show_cam_on_imaget = time.time()# 环境参数设置:
def parse_args():"""Parse input arguments."""# use 'default = ' to change parametersparser = argparse.ArgumentParser(description = 'Head pose estimation using the Hopenet network.')# gpuparser.add_argument('--gpu', dest = 'gpu_id', help = 'GPU device id to use [0]',default = 0, type = int)# use gpusparser.add_argument('--use-cuda', action = 'store_true', default = True,help = 'Use NVIDIA GPU acceleration')# path to modelparser.add_argument('--snapshot', dest = 'snapshot', help = 'Path of model snapshot.',default = 'E://Paper/Reader/Head_pose/Deep-head-pose/pre_models/hopenet_robust_alpha1.pkl',type = str)# picture pathparser.add_argument('--picture', dest = 'picture_path', help = 'Path of picture', default = 'E://Paper/Reader/''Head_pose/Deep-head-pose/''input/320_2.jpg')# bbox of pictureparser.add_argument('--bboxes', dest = 'bboxes', help = 'Bounding box annotations of frames', default = 'E://Paper/''Reader/Head_pose/Deep-head-pose/bbox/320_3.txt')# aug smoothparser.add_argument('--aug_smooth', action = 'store_true',help = 'Apply test time augmentation to smooth the CAM')# eigen smoothparser.add_argument('--eigen_smooth', action = 'store_true',help = 'Reduce noise by taking the first principle componenet of cam_weights*activations')parser.add_argument('--method', type = str, default = 'gradcam',choices = ['gradcam', 'gradcam++', 'scorecam'], help = 'Can be gradcam / gradcam++ /scorecam')args = parser.parse_args()# cuda提示符args.use_cuda = args.use_cuda and torch.cuda.is_available()if args.use_cuda:print("Using GPU for acceleration")else:print("Using CPU for computation")return argsif __name__ == '__main__':args = parse_args()# methods to show hot mapmethods = \{"gradcam": GradCAM,"scorecam": ScoreCAM,"gradcam++": GradCAMPlusPlus}# use cudnncudnn.enabled = True# bitch sizebatch_size = 32# get gpu listgpu = args.gpu_id# explanation of the model pathsnapshot_path = args.snapshot# path to pictureout_dir = 'output/pictures'# path to read picturespicture_path = args.picture_pathif args.method not in list(methods.keys()):raise Exception(f"method should be one of {list(methods.keys())}")# if directory of save not exist, create oneif not os.path.exists(out_dir):os.makedirs(out_dir)# report an error if video path not existif not os.path.exists(args.picture_path):sys.exit('picture does not exist')# ResNet50 structuremodel = hopenet.Hopenet(torchvision.models.resnet.Bottleneck, [3, 4, 6, 3], 66)print('Loading snapshot.')# Load snapshotsaved_state_dict = torch.load(snapshot_path)model.load_state_dict(saved_state_dict)print('Loading data.')# transforms of the picturestransformations = transforms.Compose([transforms.Scale(224), # resizetransforms.CenterCrop(224), transforms.ToTensor(), # center croptransforms.Normalize(mean = [0.485, 0.456, 0.406], # mean,std of (R, G, B)std = [0.229, 0.224, 0.225])])model.cuda(gpu) # transform to gpuprint('Ready to test network.')# Test the Modelmodel.eval() # Change model to 'eval' mode (BN uses moving mean/var).total = 0idx_tensor = [idx for idx in range(66)]idx_tensor = torch.FloatTensor(idx_tensor).cuda(gpu)# read picturepicture = cv2.imread(picture_path)width = int(picture.shape[1]) # shape[0]返回图片的高度height = int(picture.shape[0]) # shape[1]返回图片的宽度print('width', width)print('height', height)# Define the codec and create VideoWriter object# fourcc = cv2.VideoWriter_fourcc(*'MJPG')# rename outputs# out = cv2.VideoWriter('output/video/output-%s.avi' % args.output_string, fourcc, args.fps, (width, height))# 采用热图可视化模型# model_1 = hopenet.ResNet(torchvision.models.resnet.Bottleneck, [3, 4, 6, 3], 1000)# model_1.eval()# target_layer = model_1.layer3[-1]# print('the target layer:', target_layer)# cam = methods[args.method](model = model_1,# target_layer = target_layer,# use_cuda = args.use_cuda, )t = time.time()idx = 0count = 0# show the box bounding, try from one picturewith open(args.bboxes, 'r') as f:# return the list contain all ele exp \n ''bbox_line_list = f.read().split() # use split instead of splitlinesprint('bbox_line_list', bbox_line_list)print('length', len(bbox_line_list))# when list is not null, do:while len(bbox_line_list) > 0:line = bbox_line_list# print('line', line)# 加上跳出循环语句pic_number = line[0]# print('This is the No.%s picture' % pic_number)cv2_pic = cv2.cvtColor(picture, cv2.COLOR_BGR2RGB) # 将读取到的当前图片转换为RGB# start dict pose# 实验# print("Start detecting pose ...")# 利用 idx下标实现对于单图多人框架结构的添加x_min, y_min, x_max, y_max = int(float(line[idx + 1])), int(float(line[idx + 2])), int(float(line[idx + 3])), int(float(line[idx + 4]))# print('bbox1', x_min, y_min, x_max, y_max)bbox_width = abs(x_max - x_min)bbox_height = abs(y_max - y_min)x_min -= 50x_max += 50y_min -= 50y_max += 30x_min = max(x_min, 0)y_min = max(y_min, 0)x_max = min(picture.shape[1], x_max)y_max = min(picture.shape[0], y_max)# Crop face looselyimg = cv2_pic[y_min:y_max, x_min:x_max] # 保持长宽比例不变性img = Image.fromarray(img) # 将 array 转化为 Image# Transformimg = transformations(img)img_shape = img.size()img = img.view(1, img_shape[0], img_shape[1], img_shape[2])img = Variable(img).cuda(gpu)# capture the every frame of video, then define the three euler angles# 从hopenet网络传递回三种角度yaw, pitch, roll = model(img)# # 传入加上人物位置信息的图片参数:# 对于人物分割部分的热图分析:# rgb_img = cv2_pic[y_min:y_max, x_min:x_max]# rgb_img = cv2.resize(rgb_img, (256, 256))# rgb_img = np.float32(rgb_img) / 255# input_tensor = preprocess_image(rgb_img, mean = [0.485, 0.456, 0.406],# std = [0.229, 0.224, 0.225])# print(input_tensor)## target_category = None# cam.batch_size = 32# # use aug_smooth and eigen_smooth to smooth th vision# grayscale_cam = cam(input_tensor = input_tensor,# target_category = target_category,# aug_smooth = args.aug_smooth,# eigen_smooth = args.eigen_smooth)## grayscale_cam = grayscale_cam[0, :]# cam_image = show_cam_on_image(rgb_img, grayscale_cam)# cv2.imwrite(f'{args.method}_bbox_layer4_%s.jpg'%count, cam_image)# print('the yaw', yaw) 此时的yaw,pitch,roll是张量yaw_predicted = F.softmax(yaw)pitch_predicted = F.softmax(pitch)roll_predicted = F.softmax(roll)# Get continuous predictions in degrees.# 对张量内的元素进行求和操作;yaw_predicted = torch.sum(yaw_predicted.data * idx_tensor) * 3 - 99pitch_predicted = torch.sum(pitch_predicted.data * idx_tensor) * 3 - 99roll_predicted = torch.sum(roll_predicted.data * idx_tensor) * 3 - 99# utils.plot_pose_cube(frame, yaw_predicted, pitch_predicted, roll_predicted, (x_min + x_max) / 2,# (y_min + y_max) / 2, size = bbox_width)# 在原图的基础上,画出与头部姿态相关的三种角度utils.draw_axis(picture, yaw_predicted, pitch_predicted, roll_predicted, tdx = (x_min + x_max) / 2,tdy = (y_min + y_max) / 2, size = bbox_height / 2)# 通过输出三个角度发现,数据类型为tensor张量类型,不可用round方法# print('the sum of yaw', yaw_predicted)# print('the sum of pitch', pitch_predicted)# print('the sum of roll', roll_predicted)# Plot expanded bounding box# cv2.rectangle(picture, (x_min, y_min), (x_max, y_max), (0, 255, 0), 1)# 显现出头部姿态的三种角度;# 利用'%.2f'% 来控制输出的位数# 或者 print('{:.2f}'.format(num))cv2.putText(picture, f"Yaw: {'%.2f' % yaw_predicted}", (x_min + 45, y_min + 30), cv2.FONT_HERSHEY_COMPLEX_SMALL,0.5, (0, 255, 0), 1)cv2.putText(picture, f"Pitch: {'%.2f' % pitch_predicted}", (x_min + 45, y_min + 40),cv2.FONT_HERSHEY_COMPLEX_SMALL, 0.5, (0, 255, 0), 1)cv2.putText(picture, f"Roll: {'%.2f' % roll_predicted}", (x_min + 45, y_min + 50),cv2.FONT_HERSHEY_COMPLEX_SMALL, 0.5, (0, 255, 0), 1)# 按照原来的长宽,保存图片# 。。。路径错误导致卡了半天cv2.imwrite('E://Paper/Reader/Head_pose/Deep-head-pose/code/output/pictures/output16.jpg', picture)cv2.imshow('picture', picture)# cv2.waitKey(0)cv2.destroyAllWindows()count += 1idx += 4if idx + 4 > len(line):# 跳出循环break# # 对于加上位置信息后整体的热图# rgb_img = picture# rgb_img = cv2.resize(rgb_img, (256, 256))# rgb_img = np.float32(rgb_img) / 255# input_tensor = preprocess_image(rgb_img, mean = [0.485, 0.456, 0.406],# std = [0.229, 0.224, 0.225])# print(input_tensor)## target_category = None# cam.batch_size = 32# # use aug_smooth and eigen_smooth to smooth th vision# grayscale_cam = cam(input_tensor = input_tensor,# target_category = target_category,# aug_smooth = args.aug_smooth,# eigen_smooth = args.eigen_smooth)## grayscale_cam = grayscale_cam[0, :]# cam_image = show_cam_on_image(rgb_img, grayscale_cam)# cv2.imwrite(f'{args.method}_bbox_layer3.jpg', cam_image)print('time taken=', time.time() - t)
利用Cam对Hopenet网络模型进行可视化相关推荐
- 利用pytorch搭建LeNet-5网络模型(win11)
目录 1. 前言 2. 程序 2.1 net 2.2 train 2.3 main 3. 总结 1. 前言 手写字体识别模型LeNet5诞生于1994年,是最早的卷积神经网络之一.LeNet5通过巧妙 ...
- matlab电学成像,利用MATLAB进行电磁学计算及可视化教学.PDF
利用MATLAB进行电磁学计算及可视化教学.PDF 第 2 8 卷 第 2 期 电气电子教学学报 Vol . 28 No . 2 2006 年 4 月 J OU RN AL O F EEE Ap r ...
- HTML 利用 Web Audio API 进行音频可视化
利用Web Audio API 进行音乐可视化 1.什么是 Web Audio API: 官方:Web Audio API 提供了在Web上控制音频的一个非常有效通用的系统,允许开发者来自选音频源,对 ...
- 【Dash搭建可视化网站】项目4: 利用Dash Plotly实现数据图表可视化
手动反爬虫,禁止转载:原博地址 https://blog.csdn.net/lys_828/article/details/122073681(CSDN博主:Be_melting) 知识梳理不易,请尊 ...
- XAI之ALE:基于titanic泰坦尼克数据集对RF算法利用ALE累积局部效应图可视化算法进而实现模型可解释性案例
XAI之ALE:基于titanic泰坦尼克数据集对RF算法利用ALE累积局部效应图可视化算法进而实现模型可解释性案例 目录 基于titanic泰坦尼克数据集对RF算法利用ALE累积局部效应图可视化算法 ...
- 【置顶】利用 NLP 技术做简单数据可视化分析教程(实战)
置顶 本人决定将过去一段时间在公司以及日常生活中关于自然语言处理的相关技术积累,将在gitbook做一个简单分享,内容应该会很丰富,希望对你有所帮助,欢迎大家支持. 内容介绍如下 你是否曾经在租房时因 ...
- DL-3利用MNIST搭建神经网络模型(三种方法):1.用CNN 2.用CNN+RNN 3.用自编码网络autoencoder
Author:吾爱北方的母老虎 原创链接:https://blog.csdn.net/weixin_41010198/article/details/80286216 import tensorflo ...
- python socket发送数组_利用pyprocessing初步探索数组排序算法可视化
[经过两次更新,功能基本完成]最终效果请直接下拉到最后一个视频观看 背景说明 这篇文章旨在初步探索利用pyprocessing的强大的可视化功能,以及pyprocessing和Ipython之间的本地 ...
- 利用Python进行数据分析--绘图和可视化
转载自:http://blog.csdn.net/ssw_1990/article/details/23739953 Python有许多可视化工具,但是我主要讲解matplotlib(http://m ...
最新文章
- HTML 特殊符号编码对照表
- eclipse启动tomcat报错
- Taurus.MVC 支持Asp.Net Core 的过程
- android键盘弹出,聊天背景不变形
- php批量生成优惠券,PHP自动批量生成会员卡号程序
- pcDuino–voip服务器设置呼叫彩铃
- 帝国网站管理系统(ECMS)电影模块在IE下不能使用的解决办法
- Linux下update和upgrade的区别
- java中ImageIcon路径问题
- 马哥python全栈培训怎么样,你只需要在马哥教育待四个月
- 共享OrCAD9.2pSpice9.2+multisim下载地址
- ## 机械干了一辈子,螺栓上的8.8是什么意思
- Flutter学习笔记
- k8s不适合mysql_K8S 配置mysql配置文件不生效问题处理
- 安卓开发(简单打开前置摄像头并显示)
- 对日ODC与欧美ODC技术分析
- 在家就能拍,韩系证件照拍摄教程
- 普通高中计算机装备标准,福建省普通高中信息技术装备标准.doc
- 高德地图之添加遮盖物
- ROS2入门:turtlesim的奇妙曲线轨迹
热门文章
- 学生用计算机有哪些小游戏,学生时期:那些霸占你信息课的4款游戏,最后一款,你肯定玩过...
- [洛谷]CON1466 洛谷2017春节联欢赛 Hello Dingyou题解 Bzoj4763雪辉
- 利用python 脚本实现腾讯企业邮箱附件的批量下载
- MSP430 G2553 单片机 口袋板 日历 时钟 闹钟 万年历 电子时钟 秒表显示
- php后端开发主要会哪些技术?
- Java代码中更改imageview中引用的图片
- h5(网页) 调用相机拍照和相册,实现图片上传功能
- Guessing Camels
- Windows自启动方式完全总结
- 手机+固定电话+传真的正则