【pytorch学习】土堆pytorch笔记1

学习参考

仓库

https://github.com/xiaotudui/pytorch-tutorialhttps://github.com/xiaotudui/pytorch-tutorial

https://github.com/AccumulateMore/CV

参考博客

https://blog.csdn.net/weixin_44216612/article/details/124203730?

https://www.morinha.cc/posts/courses/pytorch-小土堆/

只做一些必要的记录,很多直接看的博客。

P3两大法宝

  • dir():打开,看见里面有多少分区、多少工具。
  • help():说明书。

在conda环境里,输入jupyter notebook,打开jupyter

Python 复制代码
import torch
print(torch.cuda.is_available())
help(torch.cuda.is_available) # 查看 torch.cuda.is_available 的用法
dir(torch)  # 查看torch包中有哪些区、有哪些工具

help代码结果:

复制代码
Help on function is_available in module torch.cuda:
is_available() -> bool
    Returns a bool indicating if CUDA is currently available.

P5加载数据

Pytorch中加载数据需要Dataset、Dataloader。

  • Dataset提供一种方式去获取每个数据及其对应的label,告诉我们总共有多少个数据。
  • Dataloader为后面的网络提供不同的数据形式,它将一批一批数据进行一个打包。

用help查看Dataset信息

Python 复制代码
from torch.utils.data import Dataset
help(Dataset)

同样可以在pycharm里按ctrl点击进去查看。

Dataset、Dataloader大概的作用

Pytorch中加载数据需要Dataset、Dataloader。

  • Dataset提供一种方式去获取每个数据及其对应的label,告诉我们总共有多少个数据。
  • Dataloader为后面的网络提供不同的数据形式,它将一批一批数据进行一个打包

使用Dataset

导入Dataset类

PYTHON 复制代码
from torch.utils.data import Dataset

"""
utils 即工具的意思,从torch这个大工具箱中挑选出的实用工具区
data  从这个工具区中挑选出的数据有关工具

前面已经介绍了如何查看帮助,可以查到Dataset的用法
①应该继承 `Dataset` 这个抽象类
②应该重写 `__getitem__` 和 `__len__` 方法
"""

PIL的一些操作(读取图片)

读取图片和显示

PYTHON 复制代码
from PIL import Image

img=Image.open(img_path)
img.show()

文件操作(路径、目录)

列出目录下的文件,路径拼接

PYTHON 复制代码
import os
# r防止转义字符生效
dir_path=r"D:\FDownload\hymenoptera_data\train\ants"

# 返回目录下一个包含这些文件和文件夹名称的列表,可以用[索引]访问
img_path_list=os.listdir(dir_path)

# 在init里截取的语句
os.path.join(self.root_dir, self.label_dir)

P7 tensorBoard

使用SummaryWriter类的方法

Python 复制代码
from torch.utils.tensorboard import SummaryWriter

"""
SummaryWriter类
	创建一个事件文件,在给定的目录中添加摘要和事件
		参数1 存放日志的文件夹名

本节视频只用到领个方法
	add_image() 在事件文件中添加图片
	add_scalar() 在TensorBoard中添加标量数据
		该方法可以用来添加训练过程中的损失值、准确率等指标,以便于在TensorBoard中进行可视化和比较
"""

SummaryWriter 是 PyTorch 中用于记录训练过程中的日志信息的工具,通常用于与 TensorBoard 配合使用。add_scalar 方法用于记录标量值(如损失函数值、准确率等)到日志中。以下是 add_scalar 方法的详细用法和示例。

方法签名

python 复制代码
add_scalar(tag, scalar_value, global_step=None, walltime=None)
  • tag :字符串,用于标识标量值的名称(如 'Loss/train''Accuracy/test')。
  • scalar_value :标量值,可以是 Python 的数字类型(如 intfloat)或 PyTorch 的张量。
  • global_step:可选参数,表示当前的全局步数(如训练的轮数或批次数)。
  • walltime:可选参数,表示事件发生的时间,以秒为单位。

示例用法

记录训练损失
python 复制代码
from torch.utils.tensorboard import SummaryWriter

# 创建一个 SummaryWriter 实例
writer = SummaryWriter(log_dir='runs/experiment_1')

# 假设你有一个训练循环
for epoch in range(num_epochs):
    train_loss = ...  # 计算训练损失
    writer.add_scalar('Loss/train', train_loss, global_step=epoch)
记录测试准确率
python 复制代码
test_accuracy = ...  # 计算测试准确率
writer.add_scalar('Accuracy/test', test_accuracy, global_step=epoch)
记录多个标量
python 复制代码
writer.add_scalar('Loss/train', train_loss, global_step=epoch)
writer.add_scalar('Loss/test', test_loss, global_step=epoch)
writer.add_scalar('Accuracy/train', train_accuracy, global_step=epoch)
writer.add_scalar('Accuracy/test', test_accuracy, global_step=epoch)

在 TensorBoard 中查看结果

  1. 启动 TensorBoard:

    bash 复制代码
    tensorboard --logdir=runs/experiment_1
  2. 打开浏览器,访问 http://localhost:6006,即可查看记录的标量值。

注意事项

  1. 日志目录

    • log_dir 是日志文件的保存路径。如果路径不存在,SummaryWriter 会自动创建。
    • 可以通过 tensorboard --logdir 指定日志目录来查看多个实验的结果。
  2. 全局步数

    • global_step 用于记录当前的训练进度。通常设置为训练的轮数或批次数。
  3. 性能影响

    • SummaryWriter 会对性能产生一定影响,尤其是在频繁写入日志时。可以通过减少写入频率来优化性能。

总结

SummaryWriteradd_scalar 方法用于记录训练过程中的标量值,如损失函数值和准确率。通过将这些值记录到日志中,可以使用 TensorBoard 可视化训练过程,帮助分析模型的性能和调试训练过程。

使用一下「tensorboard」,同时查看生成的事件文件

Python 复制代码
from torch.utils.tensorboard import SummaryWriter  
# 传入路径参数"logs"
writer = SummaryWriter("logs")  

# add_scalar(
#         tag, 相当于标题
#         scalar_value, 相当于y轴
#         global_step=None, 相当于 x轴
#     )
# y = 2x  
# 同一个图像标题下,重复修改y值会导致,新图会包含之前的旧图  
for i in range(100):  
    writer.add_scalar("y = 2x", 2*i, i)  
writer.close()
shell 复制代码
# 查看日志的命令
# logdir=事件文件所在的 文件夹名
tensorboard --logdir=logs

# 可以修改端口,改成自己的路径
tensorboard --logdir=logs --port=6007

tensorboard --logdir=learn_pytorch/logs --port=6007

添加图片

添加图片, 方便观察训练过程的不同阶段的输出

Python 复制代码
from torch.utils.tensorboard import SummaryWriter
from PIL import Image
import numpy as np

writer = SummaryWriter("logs")

# 第1步
# image_path = "data/train/ants_image/0013035.jpg"
# 第2步
image_path = "data/train/bees_image/16838648_415acd9e3f.jpg"

img_PIL = Image.open(image_path)
# 需要numpy.array类型的参数
img_array = np.array(img_PIL)
print(type(img_array))
print(img_array.shape)

# 从PIL到Numpy,需要在add_image()中指定图像的每一维的含义,需要指定高度宽度通道数的顺序
writer.add_image("test", img_array, global_step=2, dataformats="HWC")

writer.close()

P9 transforms结构及用法

什么是transforms?

常用的图像预处理方法 ,一般用于转换图片格式

有多个图片处理方法,如:

ToTensor()对象可传入两种图片格式:

  • PIL:用PIL的Image工具打开
  • numpy:用OpenCV打开

transforms该如何使用?

首先创建一个具体的工具(如ToTensor工具,相当于创建类对象):tool = transforms.ToTensor()

然后给工具传入参数(传入图片):result = tool(input)

最后得到tensor类型的图片

为什么我们需要Tensor数据类型?

tensor类型中的很多属性我们都需要在神经网络中用到,如反向传播、梯度等

所以我们必定要用到transforms将数据转换为tensor类型,然后进行训练

py 复制代码
from PIL import Image  
from torch.utils.tensorboard import SummaryWriter  
from torchvision import transforms  
  
img_path = "data/train/ants_image/0013035.jpg"  
img = Image.open(img_path)  
print(img)  
  
# 使用transforms  
"""  
ToTensor() 可传入`PIL Image` 和 `numpy.ndarray` 两种图片格式  
    PIL Image:即用PIL的Image工具打开图像的格式  
    numpy.ndarray:即用OpenCV打开图像的格式(所以一般用这种方式打开,不用再转换图像了)  
"""  
tensor_trans = transforms.ToTensor()  
tensor_img = tensor_trans(img)  
print(tensor_img)  
  
writer = SummaryWriter("logs")  
writer.add_image("Tensor_img", tensor_img, 0)  
writer.close()

了解__call__函数

transforms里有一个call函数,用下面的一段代码来说明其使用方法:

直接通过**对象(参数)**来使用

py 复制代码
# __call__ 类似「类的有参构造」,可看作为「对象-有参构造」
# 测试
class Person:  
    def __call__(self, name):  
        print("__call__"+" Hello "+name)  
  
    def hello(self, name):  
        print("Hello "+name)  
  
person = Person()  
person("zhangsan")

person.hello("lisi")

P13常用transfroms

py 复制代码
from PIL import Image
from torch.utils.tensorboard import SummaryWriter
from torchvision import transforms

writer = SummaryWriter("logs")
img = Image.open("D:\\FDownload\\hymenoptera_data\\train\\ants\\0013035.jpg")
# 打印后得知,图像为RGB三通道
print(img)

# 01 transforms.ToTensor()
trans_totensor = transforms.ToTensor()
img_tensor = trans_totensor(img)
print(img_tensor[0][0][0]) # 当使用transforms.ToTensor()将PIL图像转换为张量时,生成的张量维度遵循 (Channels, Height, Width) 格式
writer.add_image("ToTensor", img_tensor, 0)

# 02 transforms.Normalize()
# output[channel] = (input[channel] - mean[channel]) / std[channel]
trans_norm = transforms.Normalize(mean=[0.5, 0.5, 0.5], std=[0.5, 0.5, 0.5])
img_norm = trans_norm(img_tensor)
print(img_norm[0][0][0])
writer.add_image("Normalize", img_norm, 0)

# 03 Resize
# 图像为PIL,经过Resize后,仍为PIL
trans_resize = transforms.Resize((512, 512)) # 如果参数是一个int数,调整尺寸,短的那一边和参数一样,另一个进行等比例调整
img_resize = trans_resize(img)
# 将PIL转为Tensor
img_resize = trans_totensor(img_resize)
writer.add_image("Resize", img_resize, 0)

# 04 Compose 将几个转换组合在一起,先resize,再tensor
trans_resize_2 = transforms.Resize(512)
trans_compose = transforms.Compose([trans_resize_2, trans_totensor])
img_resize_2 = trans_compose(img)
writer.add_image("Resize", img_resize_2, 0)

# 05 RandomCrop
trans_random = transforms.RandomCrop(512)
trans_compose_2 = transforms.Compose([trans_random, trans_totensor])
for i in range(10):
    img_crop = trans_compose_2(img)
    writer.add_image("RandomCrop", img_crop, i)

writer.close()

dataloader

Dataloader():

概念:是一个迭代器,方便我们去多线程地读取数据,并且可以实现batch以及shuffle的读取等

用法:

test_loader = DataLoader(dataset=test_data, batch_size=4, shuffle=True, num_workers=0, drop_last=True)

如上,test_loader 就是我们生成的数据迭代器,

即加载test_data数据集,每次打包四个数据,打包成imgs和targets,

shuffle表示每次迭代完之后,下次迭代是否打乱顺序

drop_list 表示是否删除非完整页的结尾数据

完整参数参考官方文档。

P16 神经网络的基本骨架--nn.Module的使用

  • 注:nn=neural network

module

torch.nn是非常常用的包,其中torch.container中的 「Module」 是所有神经网络的基类

自己定义的模型需要实现「Module」的__init__和forward函数

一个nn.module可以视为一个块。所有的module包含两个主要函数:

复制代码
init函数:在里边定义一些需要的类或参数。包括网络层

forward函数:做最终的计算和输出,其形参就是模型(块)的输入。
PYTHON 复制代码
import torch
from torch import nn


class Lana(nn.Module):
    # ctrl+ o 可以找到有哪些方法要重写
    def __init__(self) -> None:
        super().__init__()

    def forward(self,input):
        output = input + 1
        return output

lana=Lana()
x=torch.tensor(1.0)
print(x)
output = lana(x)
print(output)
相关推荐
小王努力学编程34 分钟前
美团2024年春招第一场笔试 C++
开发语言·数据结构·c++·学习·算法
卡皮巴拉爱吃小蛋糕37 分钟前
MySQL的事务(Transaction)【学习笔记】
数据库·笔记·学习·mysql
superior tigre38 分钟前
C++学习:六个月从基础到就业——STL算法(一) 基础与查找算法
c++·学习·算法
jackson凌1 小时前
【Java学习方法】终止循环的关键字
java·笔记·学习方法
麻溜学习1 小时前
IP地址与子网掩码
笔记
EQ-雪梨蛋花汤2 小时前
【Unity笔记】Unity 编辑器扩展:一键查找场景中组件引用关系(含完整源码)(组件引用查找工具实现笔记)
笔记·unity·编辑器
gbase_lmax2 小时前
gbase8s存储学习一 rootdbs存储结构以及寻址分析
数据库·学习
旺代3 小时前
Vue3速通笔记
vue.js·笔记
笺上山河梦3 小时前
C++ 的 输入输出流(I/O Streams)
开发语言·c++·学习·算法