文章目录
本课程来自深度之眼deepshare.net,部分截图来自课程视频。
内容简介
学习TensorBoard中scalar与histogram的使用;学习TensorBoard中Image与PyTorch的make_grid使用
具体来说就是学习下面六个图的可视化。
SummaryWriter
功能:提供创建event file的高级接口
主要属性:
·log_dir:event file输出文件夹,默认是不指定,如果不指定,就会在py文件的当前文件夹下面创建一个runs文件夹,在文件夹下面会有一系列文件夹XXX,然后再下面才是event file文件YYY;如果指定,那么下面的comment参数就不会生效。通常是要设置的,把代码和数据分开,便于管理。
·comment:不指定log_dir时,文件夹后缀,就是上面XXX的后缀
·filename_suffix:event file文件名后缀,就是上面YYY的后缀
例子:
logdir="./train_log/test_log dir"
writer=Summarywriter(log dir=log dir, comment='_scalars', filename_suffix="12345678")
writer=Summarywriter(comment='_scalars',filename _suffix="12345678")
add_scalar & add_histogram
1.add_scalar()
功能:记录标量
·tag:图像的标签名,图的唯一标识,下图中箭头那个东西就是tag
·scalar_value:要记录的标量
·global_step:x轴
2.add_scalars()
·main_tag:该图的标签,同上面的tag,当图中有多个曲线,就是整个图的主标签,各个曲线的tag会放到字典中。
·tag_scalar_dict:key是变量的tag,value是变量的值
3.add histogram()
功能:统计直方图与多分位数折线图
·tag:图像的标签名,图的唯一标识
·values:要统计的参数
·global_step:y轴,从代码上面来看,貌似就是对应的epoch
·bins:取直方图的bins
4.add_image()
功能:记录图像
·tag:图像的标签名,图的唯一标识
·img_tensor:图像数据,注意尺度,这里要注意:当输入的数据都是0~1区间,则会把数据都乘以255,如果数据区间超过了0 ~ 1,那么不乘以255,总之就是要把图像缩放到0-255这个区间。
·global_step:x轴
·dataformats:数据形式:CHW,HWC,HW,C是channel
5.torchvision.utils.make_grid
功能:制作网格图像(就是一个坐标轴里面显示多个图片)
·tensor:图像数据,BCH*W形式,其中B是batchsize
·nrow:行数(列数自动计算)(例如:batchsize为16,nrow设置为4,则列数自动计算得到4)
·padding:图像间距(像素单位)就是上面的网格的宽度
·normalize:是否将像素值标准化(根据数据的区间来设置)
·range:标准化范围
·scale_each:是否单张图维度标准化
·pad_value:padding的像素值
模型指标监控
用人民币二分类为例,将模型中的各种指标用tensorboard进行可视化,主要是演示为主,就不截图了。
AlexNet卷积核与特征图可视化
# -*- coding:utf-8 -*-
"""
@file name : weight_fmap_visualization.py
# @author : TingsongYu https://github.com/TingsongYu
@date : 2019-10-25
@brief : 卷积核和特征图的可视化
"""
import torch.nn as nn
from PIL import Image
import torchvision.transforms as transforms
from torch.utils.tensorboard import SummaryWriter
import torchvision.utils as vutils
from tools.common_tools import set_seed
import torchvision.models as models
set_seed(1) # 设置随机种子
# ----------------------------------- kernel visualization -----------------------------------
# flag = 0
flag = 1
if flag:
#构建writer
writer = SummaryWriter(comment='test_your_comment', filename_suffix="_test_your_filename_suffix")
#获取一个训练好的Alexnet,直接用的是torchvision.models中的模型,而且是预训练好的
alexnet = models.alexnet(pretrained=True)
kernel_num = -1
vis_max = 1#最大可视化层,这里只可视化到0和1两个卷积核
for sub_module in alexnet.modules():
if isinstance(sub_module, nn.Conv2d):
kernel_num += 1
if kernel_num > vis_max:#根据这个数字判断是否进行可视化
break
kernels = sub_module.weight
c_out, c_int, k_w, k_h = tuple(kernels.shape)#c_int是输入,是rgb图像,c_out应该是卷积核,第一层有64个
for o_idx in range(c_out):
kernel_idx = kernels[o_idx, :, :, :].unsqueeze(1) # make_grid需要 BCHW(四个维度),所以这里拓展C维度
#这里是要学习的函数
kernel_grid = vutils.make_grid(kernel_idx, normalize=True, scale_each=True, nrow=c_int)
writer.add_image('{}_Convlayer_split_in_channel'.format(kernel_num), kernel_grid, global_step=o_idx)
kernel_all = kernels.view(-1, 3, k_h, k_w) # 3, h, w不符合四个维度要处理
kernel_grid = vutils.make_grid(kernel_all, normalize=True, scale_each=True, nrow=8) # c, h, w这里注意,卷积核有64个,分成8行,所以计算出来就是8列。
writer.add_image('{}_all'.format(kernel_num), kernel_grid, global_step=322)
print("{}_convlayer shape:{}".format(kernel_num, tuple(kernels.shape)))
writer.close()
# ----------------------------------- feature map visualization -----------------------------------
# flag = 0
flag = 1
if flag:
writer = SummaryWriter(comment='test_your_comment', filename_suffix="_test_your_filename_suffix")
# 数据
path_img = "./lena.png" # 蕾娜your path to image
normMean = [0.49139968, 0.48215827, 0.44653124]
normStd = [0.24703233, 0.24348505, 0.26158768]
norm_transform = transforms.Normalize(normMean, normStd)
img_transforms = transforms.Compose([
transforms.Resize((224, 224)),
transforms.ToTensor(),
norm_transform
])
img_pil = Image.open(path_img).convert('RGB')#读取进来是pil格式
if img_transforms is not None:
img_tensor = img_transforms(img_pil)
img_tensor.unsqueeze_(0) # chw --> bchw添加batchsize维度
# 模型
alexnet = models.alexnet(pretrained=True)
# forward手工获取第一个特征层,不这样的话PyTorch会自动释放
# 下节课讲解的hook有更加好的方式来获取中间层结果
convlayer1 = alexnet.features[0]
fmap_1 = convlayer1(img_tensor)
# 预处理
fmap_1.transpose_(0, 1) # bchw=(1, 64, 55, 55) --> (64, 1, 55, 55)这里吧batchsize维度放到第一个
fmap_1_grid = vutils.make_grid(fmap_1, normalize=True, scale_each=True, nrow=8)
writer.add_image('feature map in conv1', fmap_1_grid, global_step=322)
writer.close()
这里是代码第一个flag运行的结果:
然后用tensorboard打开event file
0_Convlayer_split_in_channel结果,可以拖动查看每一个step的结果:
总的可视化
第二个卷积核比较小,所以特征看的不是很明显:
然后后是第二个flag执行结果:
得到的第一个特征图
add_graph and torchsummary
add_graph()
功能:可视化模型计算图
·model:模型,必须是nn.Module
·input_to_model:输出给模型的数据
·verbose:是否打印计算图结构信息。这个功能1.2版本有问题,1.3才能用。可以用conda额外配置一个虚拟环境
torchsummary需要pip额外安装
功能:查看模型信息,便于调试
·model:pytorch模型
·input_size:模型输入size
·batch_size:batch size
·device:“cuda"or“cpu"
from torchsummary import summary
print(summary(lenet,(3,32,32),device="cpu"))
github:https://github.com/sksq96/pytorch-summary
#作业:
- 可视化任意网络模型训练的Loss,及Accuracy曲线图,Train与Valid必须在同一个图中
- 采用make_grid,对任意图像训练输入数据进行批量可视化