zoukankan      html  css  js  c++  java
  • 2. tensorboard和 transform的使用

    本篇文章主要介绍 pytorch 中 tensorboard 和 transform 的使用。

    1、tensorboard

    tensorboard原本是tensorflow的可视化工具,pytorch从1.2.0开始支持tensorboard。之前的版本也可以使用tensorboardX代替。
    tensorboard常常作为一个辅助工具,可以把Pytorch中的参数传递到Tensorboad上面。

         tensorboard 的打开与关闭

    tensorboard 作为一个可视化的辅助工具,是通过将日志文件写入到我们的目标文件夹中实现
    既然是通过文件的写入和读取来实现的,那么必定包含文件的打开与关闭操作,具体的代码如下所示:

    from torch.utils.tensorboard import SummaryWriter
    # 创建一个对象,并设置存储路径
    writer = SummaryWriter('./logs')
    
    writer.close()
    

         add_image(), add_scalar()

      了解文件的打开与关闭之后,下一步就是如何向日志文件中写入数据,这里主要是介绍最为常用的两个方法 SummaryWriter.add_image() 和 SummaryWriter.add_scalar()

    1. SummaryWriter.add_scalar()
      首先,查看帮助文档


    不能不夸奖一般 Pycharm 的帮助文档,写的非常详细(ctrl键按住,点击函数名即可)

    那么,我们也写一个

    from torch.utils.tensorboard import SummaryWriter
    # 创建一个对象,并设置存储路径
    writer = SummaryWriter('./logs')
    for i in range(20):
      writer.add_scalar("my:y=2x", i * 2, i)
    writer.close()
    
    1. SummaryWriter.add_image()
      帮助文档如下:


    同样是照着葫芦画瓢,走一个

    from torch.utils.tensorboard import SummaryWriter
    # 用于读取图像和类型转化
    from PIL import Image 
    import numpy as np
    
    # 创建一个对象,并设置存储路径
    img_path = r"F:projectspycharmpytorch_dl	estdata	rainants013035.jpg"
    writer = SummaryWriter('./logs')
    
    img_PIL = Image.open(img_path)
    img_array = np.array(img_PIL)
    writer.add_image("test_img", img_array, 0, dataformats="HWC")
    
    writer.close()
    

         tensorboard 通过端口查看数据

    需要在环境中cmd运行

    tensorboard --logdir=logs 
    tensorboard --logdir=./logs --port=6066
    

    默认端口号是6006,通过--port 参数我们可以指定特定的端口


         tag 冲突处理

    当我们在同一个 log 文件夹中,指定了同一个 tag,可能会照成显示图像的混乱,解决这个问题可以有以下这几个方法

    1. 更改日志文件存储位置

    2. 删除原本的日志文件

    这两种方法都需要重启我们的 tensorboard 命令,ctrl + c 终止原本的 tenforboard 进程,然后开启新的 tensorboard进程即可

    2、transform的使用

         transform 的简单使用与 Tensor 数据类型

    transform 顾名思义,就是用于数据类型转化的意思,他是torchvision模块下面的一个子模块transforms,该模块中包含大量用户数据类型转化的类型和方法。下面我们进入该模块中进行查看。 (注:pycharm 中 按住 ctrl 单机进去该模块即可)


    常用的主要是一下这几个类:
    Compose:通过查看帮助文档可知,他是 多个 transform 的结合体,也就是说可以进行多次 transform 变化
    ToTensor:


    PILToTensor : Converts a PIL Image (H x W x C) to a Tensor of shape (C x H x W). 也是进行了类型的转换设置维度信息发生了变化

    其他的请自行查看帮助文档,这里不再赘述。

    下面,我进行一下简单使用的演示:

    from torch.utils.tensorboard import SummaryWriter
    from torchvision import transforms
    from PIL import Image
    import numpy as np
    
    
    img_path = r'F:projectspycharmpytorch_dl	estdata	rainants5650366_e22b7e1065.jpg'
    img_PIL = Image.open(img_path)
    img_array = np.array(img_PIL)
    
    tensor_trans = transforms.ToTensor()
    
    img_tensor1 = tensor_trans(img_PIL)
    img_tensor2 = tensor_trans(img_array)
    
    writer = SummaryWriter('logs2')
    writer.add_image('test1', img_tensor1, 0)
    writer.add_image('test1', img_tensor2, 1)
    
    writer.close()
    


    查看转换之后的 tensor 类型,可以看到一些专美用于做神经网络的属性,可以说tensor很大程度上是为了方面深度学习代码的书写(就像是 numpy 用于科学计算一样),
    上面的代码中我们也使用 tensor,将其写在 Log 文件的 日志中去


         常见 transform 的使用

        这里,我先引入一个小知识 pytorch 中类的 __call__函数和 forward函数都不用显示的调用函数,
    这两个函数的作用是能够让python中的类的对象能够像方法一样被调用!具体可以参考博客:
    深入探究# PyTorch中的 forward() 方法详解

    transform 非常的常见,常常用于转化数据的格式(上一节有着些许的介绍),下面我将进行更为详细的介绍。
    我们的函数的认知(尤其是库函数),主要从一下三种方面出发:

    1. 函数的作用 -- 这也是我们使用该函数的目的已经应用场景
    2. 函数的输入格式 -- 教会我们如何使用函数
    3. 函数的输出格式

    在我看来,想要快速的了解函数的功能与使用方法,上手一个函数,还是需要看官方文档,幸好Pycharm IDE 中集成了帮助文档,虽然英文,不过写的足够详细,下面我将一个一个的介绍 transform 模块的常用函数

    首先,我们还是大致看一下 transform.py 中的函数


    下面,我们查看官方文档 + 使用 tensorboard 进行查看函数的作用
    首先,我们先说2个小技巧:

    1. 输入代码的时候 ctrl + p可以提示函数参数
    2. 设置代码提示是是否忽略大小写(参考下午)


         ToPILImage


    我们使用 cv2.read() 和 Image.open()分别进行读取图片,将其放入到 logs 文件中,通过 tensorboard进行查看

    # 导入几个包
    from torchvision.transforms import transforms
    from torch.utils.tensorboard import SummaryWriter
    from PIL import Image
    import cv2
    import numpy as np
    
    # define the variable and open tensorboard
    writer = SummaryWriter('logs')
    img_path = r'F:projectspycharmpytorch_dl	estdatavalees72100438_73de9f17af.jpg'
    
    # read the image
    img_array = cv2.imread(img_path)  # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR,
    trans_toPIL = transforms.ToPILImage()
    trans_toTensor = transforms.ToTensor()
    img_PIL = trans_toPIL(img_array)    # 调用了 __call__ 函数,转化形成 PIL
    img_PIL_2 = Image.open(img_path)  # 直接读的 PIL图片格式
    print(type(img_array))
    writer.add_image('ndarrayy - PILImage - PILImage', img_array, 0, dataformats="HWC")
    writer.add_image('ndarrayy - PILImage - PILImage', trans_toTensor(img_PIL), 1)
    writer.add_image('ndarrayy - PILImage - PILImage', trans_toTensor(img_PIL_2), 2)
    
    # close tensorboard
    writer.close()
    



    发现颜色出了问题
    其实这不是cv2读取文件出现了问题,而是我们cv2读取文件 读取通道顺序为B、G、R
    和我们平时的 RGB 顺序完全相反,所以造成了这种奇奇怪怪的现象,将其修改也较为简单

    # 第一种方法,推荐使用该种方法,因为第一种方法存在问题
    # 尤其是在转换 tensor的时候,我的 pycharm 会直接 报错,异常退出,我还找了半天bug
    b,g,r = cv2.split(img_array)			#分别提取B、G、R通道
    img_array = cv2.merge([r, g, b])    # 可以将其写成一个函数封装一下子了
    
    # 第二种方法
    #img[:,:,0]表示图片的蓝色通道,对一个字符串s进行翻转用的是s[::-1],同样img[:,:,::-1]就表示BGR通道翻转,变成RGB
    img_array = img_array[:, :, ::-1]
    

    转化之后,再次运行一下,发现颜色正常。
    注意:一定要将之前的 event 日志全部给删除,然后重启我们的 tensorboard 工具


    这里,我再进行一下 cv2 的些许补充,主要是对下述代码进行讲解,具体请看注释

    # 导入几个包
    import matplotlib.pyplot as plt
    from torchvision.transforms import transforms
    from torch.utils.tensorboard import SummaryWriter
    from PIL import Image
    import cv2
    import numpy as np
    
    # define the variable and open tensorboard
    writer = SummaryWriter('logs')
    img_path = r'F:projectspycharmpytorch_dl	estdatavalees72100438_73de9f17af.jpg'
    
    # read the image
    img_array_bgr = cv2.imread(img_path)  # 首先我们使用了 cv2 库函数读取了图片,bgr色彩,ndarray类型
    img_PIL = Image.open(img_path)   # 我们又使用了 Image 类读取了图片 PIL 类型
    b, g, r = cv2.split(img_array_bgr)  # 这一步,我们使用 bgr分离,将 img_array_bgr --> img_array_rgb
    img_array_rgb = cv2.merge([r, g, b])
    cv2.imshow("img_array", img_array_rgb)
    cv2.waitKey()
    cv2.imshow("img_array", img_array_bgr)
    cv2.waitKey()
    
    # 我们将 rgb, bgr 分别转换为 PIL 进行 show展示
    img_PIL.show()
    trans_toPIL = transforms.ToPILImage()
    img_PIL_rgb = trans_toPIL(img_array_rgb)
    img_PIL_rgb.show()
    img_PIL_bgr = trans_toPIL(img_array_bgr)
    img_PIL_bgr.show()
    
    # close tensorboard
    writer.close()
    




    rgb和 img_PIL_Image_open都是一个图片


    心得:
    不难看出,cv2读取读片是 bgr, 解析显示图片也是 bgr,所以说仅仅是在 cv2 中使用,不需要进行 bgr->rgb 维度的转换,但是倘若cv2中混有 tensor,或者是 PIL因为他们使用了rgb 色系,应当进行相应类型的转换。

         toTensor

    这个之前讲过,也用过很多次,这里不再赘述(而且用法和 toPILImage 差不多)

         Resize

    帮助文档的解释如下图所示:


    直接找一个图进行实践即可(效果显著,像素变得非常的拉胯!!!)

    # 导入几个包
    import matplotlib.pyplot as plt
    from torchvision.transforms import transforms
    from torch.utils.tensorboard import SummaryWriter
    from PIL import Image
    import cv2
    import numpy as np
    
    # define the variable and open tensorboard
    writer = SummaryWriter('logs')
    img_path = r'F:projectspycharmpytorch_dl	estdatavalees72100438_73de9f17af.jpg'
    
    # read the image
    img_array = cv2.imread(img_path)  # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR,
    # img_array = img_array[:, :, ::-1]
    b, g, r = cv2.split(img_array)
    img_array2 = cv2.merge([r, g, b])
    img_array3 = img_array[:, :, ::-1]
    img_array = img_array2
    
    
    trans_toPIL = transforms.ToPILImage()
    trans_toTensor = transforms.ToTensor()
    trans_resize = transforms.Resize(100)
    trans_resize2 = transforms.Resize([100, 50]) # 注意这个[],因为他是一个序列 list
    img_tensor = trans_toTensor(img_array)
    img_tensor_resize = trans_resize.forward(img_tensor)
    img_tensor_resize2 = trans_resize2.forward(img_tensor)
    writer.add_image("img_tensor_resize", img_tensor, 0)
    writer.add_image("img_tensor_resize", img_tensor_resize, 1)
    writer.add_image("img_tensor_resize", img_tensor_resize2, 2)
    
    # close tensorboard
    writer.close()
    

    debug 查看他的像素值变化:





         Normalize

    Normalize,规范化,特殊情况下也可以成为归一化,
        归一化就是要把需要处理的数据经过处理后(通过某种算法)限制在你需要的一定范围内。首先归一化是为了后面数据处理的方便,其次是保证程序运行时收敛加快。归一化的具体作用是归纳统一样本的统计分布性。归一化在0-1之间是统计的概率分布,归一化在某个区间上是统计的坐标分布。归一化有同一、统一和合一的意思。
        归一化的目的简而言之,是使得没有可比性的数据变得具有可比性,同时又保持相比较的两个数据之间的相对关系,如大小关系;或是为了作图,原来很难在一张图上作出来,归一化后就可以很方便的给出图上的相对位置等。

    帮助文档的解释如下图所示:


    走一个小代码试一试

    # 导入几个包
    import matplotlib.pyplot as plt
    from torchvision.transforms import transforms
    from torch.utils.tensorboard import SummaryWriter
    from PIL import Image
    import cv2
    import numpy as np
    
    # define the variable and open tensorboard
    writer = SummaryWriter('logs')
    img_path = r'F:projectspycharmpytorch_dl	estdatavalees72100438_73de9f17af.jpg'
    
    # read the image
    img_array_bgr = cv2.imread(img_path)  # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR,
    img_PIL = Image.open(img_path)
    b, g, r = cv2.split(img_array_bgr)
    img_array_rgb = cv2.merge([r, g, b])
    
    trans_to_tensor = transforms.ToTensor()
    trans_to_PIL = transforms.ToPILImage()
    trans_to_norm = transforms.Normalize([1, 2, 3], [3, 4, 5])
    img_tensor = trans_to_tensor(img_array_rgb)
    img_tensor_norm = trans_to_norm(img_tensor)
    writer.add_image("Image-Normalize", img_tensor, 0)
    writer.add_image("Image-Normalize", img_tensor_norm, 1)
    
    # close tensorboard
    writer.close()
    

    倘若你的 tensorboard 出现了问题,请记得退出你的 tensorboard 进程,并且删除你的日志文件,在此运行改程序,倘若还有问题,可能是你的代码、或者是环境出了问题。



         Compose

    帮助文档的解释如下图所示:


    直接进行上手实验,我们连接一个 ToTensor、Resize 、 Normalize 的转换器,代码如下图所示:

    # 导入几个包
    import matplotlib.pyplot as plt
    from torchvision.transforms import transforms
    from torch.utils.tensorboard import SummaryWriter
    from PIL import Image
    import cv2
    import numpy as np
    
    # define the variable and open tensorboard
    writer = SummaryWriter('logs')
    img_path = r'F:projectspycharmpytorch_dl	estdatavalees72100438_73de9f17af.jpg'
    
    # read the image
    img_array_bgr = cv2.imread(img_path)  # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR,
    img_PIL = Image.open(img_path)
    b, g, r = cv2.split(img_array_bgr)
    img_array_rgb = cv2.merge([r, g, b])
    
    
    trans_to_tensor = transforms.ToTensor()
    trans_compose = transforms.Compose([
        transforms.ToTensor(),
        transforms.Resize(200),
        transforms.Normalize([1, 2, 3], [1, 2, 3])
    ])
    
    img_compose = trans_compose(img_array_rgb)
    writer.add_image("Compose", trans_to_tensor(img_array_rgb), 0)
    writer.add_image("Compose", img_compose, 1)
    
    # close tensorboard
    writer.close()
    

    结果如下所示:



         CenterCrop

    帮助文档的解释如下图所示:


    直接上代码:

    # 导入几个包
    import matplotlib.pyplot as plt
    from torchvision.transforms import transforms
    from torch.utils.tensorboard import SummaryWriter
    from PIL import Image
    import cv2
    import numpy as np
    
    # define the variable and open tensorboard
    writer = SummaryWriter('logs')
    img_path = r'F:projectspycharmpytorch_dl	estdatavalees72100438_73de9f17af.jpg'
    
    # read the image
    img_array_bgr = cv2.imread(img_path)  # 其实并不是失真,而是在导入图片时使用了opencv,正常展示顺序是RGB,而opencv的读取顺序是BGR,
    img_PIL = Image.open(img_path)
    b, g, r = cv2.split(img_array_bgr)
    img_array_rgb = cv2.merge([r, g, b])
    
    
    trans_to_tensor = transforms.ToTensor()
    trans_center_crop = transforms.CenterCrop((100, 100))
    
    img_tensor = trans_to_tensor(img_array_rgb)
    img_center_crop = trans_center_crop(img_tensor)
    writer.add_image("Image-center-crop", img_tensor, 0)
    writer.add_image("Image-center-crop", img_center_crop, 1)
    
    # close tensorboard
    writer.close()
    



         pycharm 的小技巧

    1. pycharm 的断点调试,非常的好使,主要是因为他还至此在断点中查看变量的数值,并且可以进行变量的修改,简直就是和 Python console 一样,用起来都很爽



    1. pycharm ctrl + p 查看代码提示


    1. 顺便提一嘴,查看帮助文档的时候,尽量自己查看,不要使用翻译软件(不是很准),主要是注意 输入、输出和函数的功能
    2021/11/9
  • 相关阅读:
    redis缓存问题解决方案
    JVM 2-垃圾收集及内存分配策略
    JVM 1-内存管理
    mysql数据库基础
    事务学习
    使用redis分布式锁来解决集群项目的定时任务冲突问题
    Spring AOP学习
    Spring IOC
    java语言基础7--线程相关类
    多重背包的二进制优化——DP
  • 原文地址:https://www.cnblogs.com/lucky-light/p/15528038.html
Copyright © 2011-2022 走看看