欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Windows Terminal 使用TensorBoard可视化方法

程序员文章站 2022-07-02 22:31:19
...

参考:https://github.com/TingsongYu/PyTorch_Tutorial

配置部分

1、点击终端的设置,修改settings.json文件中之前配置好的连接服务器的代码("list"部分),如下:

 {
     "guid": "{通过在线生成获取}",
     "hidden": false,
     "name": "自定义服务器名字",
     "commandline": "powershell.exe ssh -L 16006:127.0.0.1:6006 用户名@ip地址 -p端口号"
 }

2、训练模型(下文给出),建立日志目录(mkdir)

3、终端输入:

tensorboard --logdir="./log_path" --port=6006

4、本地浏览器即可访问:

127.0.0.1:16006

训练模型可视化部分------使用TensorBoardX类

1、常用可视化函数

  • add_scalar():可用于loss/accuracy单个曲线记录,示例:
    from torch.utils.tensorboard import SummaryWriter
    import numpy as np
    
    writer = SummaryWriter()
    
    for n_iter in range(100):
        writer.add_scalar('Loss/train', losstr.item(), n_iter)
        writer.add_scalar('Loss/test', lossva.item(), n_iter)
        writer.add_scalar('Accuracy/train', acctr.item(), n_iter)
        writer.add_scalar('Accuracy/test', accva.item(), n_iter)
    
  • add_scalars():多个曲线对比记录
    from torch.utils.tensorboard import SummaryWriter
    import numpy as np
    
    writer = SummaryWriter()
    
    for n_iter in range(100):
        writer.add_scalars('Loss/Accuracy', {'loss': loss.item(), 'acc': acc.item()}, n_iter)
    
  • add_histogram():监测权值和梯度的分布变化情况
    for n_iter in range(100):
        for name, param in model.named_parameters():
            writer.add_histogram(name + '_grad', param.grad, n_iter)
            writer.add_histogram(name + '_data', param, n_iter)
    
  • add_image():检查模型的输入,监测feature map的变化

    make_grid():将一组图片拼接成一张图片可视化

    import  torchvision.utils as utils
    for n_iter in range(100):
        if n_iter % 10 == 0:
            # img (B*C*H*W); nrow: 行数; scale_each:是否单张图片标准化
            x = utils.make_grid(img, nrow=4, normalize=True, scale_each=True) 
        	writer.add_image('Image', x, n_iter)  # x.size:(3, 266, 530) (C*H*W)
    
  • add_graph():网络结构拓扑图
    model = Net().to(device)
    input = torch.rand(B, C, H, W)
    writer.add_graph(model, input)
    
  • add_embedding():在三维空间或二维空间展示数据分布(T-SNE/PCA/CUSTOM三种方法)
    images = train_set.train_data[:100].float()
    label = train_set.train_label[:100]
    # 将二维图片转成一维数据   D: 特征维数
    features = images.view(100, D)  
    # label_img: 空间中展示的图片,shape=(N, C, H, W),N为类别数
    writer.add_embedding(features, metadata=label, label_img=images.unsqueeze(1))
    
  • add_text():添加文本,输出需要的信息
    for n_iter in range(100):
        writer.add_text('CNN', 'this is epoch ' + str(n_iter), n_iter)
    
  • add_figure():添加一个matplotlib图像并显示,与add_image()类似
    writer.add_figure('ImageName', plt, n_iter, dataformats='NCHW')
    
  • add_image_with_boxes():图像中绘制Box,目标检测用
    # img_tensor:默认(3, H, W)
    # box_tensor:(xmin, ymin, xmax, ymax)
    writer.add_image_with_boxes(tag, img_tensor, box_tensor, global_step=None, walltime=None, dataformats='CHW', labels=None, **kwargs)
    
  • add_pr_curve():添加精度召回曲线
    # labels/predictions:numpy数据
    writer.add_pr_curve('pr_curve', labels, predictions, n_iter)
    

2、卷积核可视化

#卷积核可视化
def show_kernal(model):
    # 可视化卷积核
    for name, param in model.named_parameters():
        if 'conv' in name and 'weight' in name:
            c_int = param.size()[1] # 输入通道数
            c_out = param.size()[0]  # 输出通道,表示卷积核的个数
            
            # 将一个卷积层的卷积核绘制在一起,每一行是一个feature map的卷积核
            k_w, k_h = param.size()[-1], param.size()[-2]
            kernel_all = param.view(-1, 1, k_w, k_h)
            kernel_grid = vutils.make_grid(kernel_all, normalize=True, scale_each=True, nrow=c_int)  # 1*输入通道数, w, h
            writer.add_image(k + '_all', kernel_grid, global_step=666)
writer.close()

3、特征图可视化

import torchvision.utils as vutils
# 获取图片
test_loader = DataLoader(dataset=test_data, batch_size=1)
img, label = iter(test_loader).next()
writer = SummaryWriter(log_dir=log_dir)
for name, layer in net._modules.items():
    # 为fc层预处理x
    x = x.view(img.size(0), -1) if "fc" in name else x
    # 对x执行单层运算
    x = layer(x)
    print(x.size())
    # 由于__init__()相较于forward()缺少relu操作,需要手动增加
    x = F.relu(x) if 'conv' in name else x

    # 依据选择的层,进行记录feature maps
    if  'layer' in name or 'conv' in name:
        # 绘制feature maps,若图片为CBHW,转为BCHW,单通道特征图
        x1 = x.transpose(0, 1) 
        img_grid = vutils.make_grid(x1, normalize=True, scale_each=True, nrow=2)  # B,C, H, W
        writer.add_image(vis_layer + '_feature_maps', img_grid, global_step=666)

writer.close()

4、梯度及权值可视化

通过记录每个epoch的梯度值来监测梯度情况、记录权值、分析权值更新的方向。

for n_iter in range(100):
    for name, layer in net.named_parameters():
        writer.add_histogram(name + '_grad', layer.grad.cpu().data.numpy(), n_iter)
        writer.add_histogram(name + '_data', layer.cpu().data.numpy(), n_iter)

注意:

  • 关于权值weights

    权值最开始是一个标准的相对集中的高斯分布,越到后期,权值随着训练不断扩大。但是权值太大容易导致过拟合,因为模型的输出值会被该特征所主导,从而产生过拟合,此时可以通过**设置更大的权值衰减(weight_decay)**来缓解。

  • 关于偏置bias

    每个类别随着训练的进行,都有相对固定的bias大小,若某个类别的bias特别大或特别小,其**召回率(某一类别的图片预测正确的概率)**会很低

  • 关于梯度

    倘若前几层网络的梯度非常小,可能是梯度流通不畅导致,可以考虑残差结构或辅助残差结构层等trick来解决梯度消失。同时可为梯度小的层设置更学习率,梯度大的层设置小的学习率

5、混淆矩阵及其可视化

混淆矩阵常用来观察分类结果,其获取:

conf_mat = np.zeros([cls_num, cls_num])
for i in range(len(labels)):
    true_i = np.array(labels[i])
    pre_i = np.array(predicted[i])
    conf_mat[true_i, pre_i] += 1.0
    

confusion_mat_N = conf_mat.copy()
for i in range(len(classes_name)):
    confusion_mat_N[i, :] = conf_mat[i, :] / conf_mat[i, :].sum()

    # 获取颜色
    cmap = plt.cm.get_cmap('Greys')  # 更多颜色: http://matplotlib.org/examples/color/colormaps_reference.html
    plt.imshow(confusion_mat_N, cmap=cmap)
    plt.colorbar()

    # 设置文字 classes_name: list,各类别名称
    xlocations = np.array(range(len(classes_name)))
    plt.xticks(xlocations, classes_name, rotation=60)
    plt.yticks(xlocations, classes_name)
    plt.xlabel('Predict label')
    plt.ylabel('True label')
    plt.title('Confusion_Matrix_valid')

    # 打印数字
    for i in range(confusion_mat_N.shape[0]):
        for j in range(confusion_mat_N.shape[1]):
            plt.text(x=j, y=i, s=int(confusion_mat[i, j]), va='center', ha='center', color='red', fontsize=10)
            # 保存
            plt.savefig('Confusion_Matrix_valid.jpg')
            plt.close()