关于Pytorch笔记总结

关于Pytorch笔记总结

前言

主要是对自己看的一些东西总结的笔记,然后把主要看的地址先贴在这里方便大家找原作者:

bilbil up 牛奶奶:
https://www.bilibili.com/video/BV1UR4y1t7Cm?spm_id_from=333.999.0.0

知乎:
https://bbs.cvmart.net/articles/3663

一.关于它的主要结构

1.它实现模型训练的5大要素
在这里插入图片描述

2.每个结构的主要功能

  • 数据:包括数据读取,数据清洗,进行数据划分和数据预处理,比如读取图片如何预处理及数据增强。
  • 模型:包括构建模型模块,组织复杂网络,初始化网络参数,定义网络层.
  • 损失函数:包括创建损失函数,设置损失函数超参数,根据不同任务选择合适的损失函数。
  • 优化器:包括根据梯度使用某种优化器更新参数管理模型参数,管理多个参数组实现不同学习率,调整学习率。
  • 迭代训练组织上面 4 个模块进行反复训练。包括观察训练效果,绘制 Loss/ Accuracy 曲线,用 TensorBoard 进行可视化分析。

二.从每一个功能粗略的看起(快速搭建)

第一:dataset

dataset是数据集,但是在Pytorch中dataset ** 并不是数据集本身 而是一个个类的实例**(就是一个实例化的对象)dataset它的基类就是torch.utils.data.Dataset。

dataset必须重写

__getitem__:获取数据的方法
__len__:返回dataset的size,即返回数据大小

为什么要用 __ ???

__getitem__ == getitem[i]
__len__ =len()
一样的,因为python提供了magic methods

魔术方法,指python中所有以”__”(双下划线)作为名字开头和结尾的方法。都可以用更简便的方法调用,像函数一样使用。

第二:把image转为Tensor(pytorch处理Tensor)

form torchvision import transforms
'''
transforms模块中的方法可以把数据转换成我们需要的格式
'''

关于torchvision中构成一览

  • torchvision.datasets: 一些加载数据的函数及常用的数据集接口;
  • torchvision.models: 包含常用的模型结构(含预训练模型),例如AlexNet、VGG、ResNet等;
  • torchvision.transforms: 常用的图片变换,例如裁剪、旋转等;
  • torchvision.utils: 其他的一些有用的方法。
    ————————————————
    原文链接:https://blog.csdn.net/wangkaidehao/article/details/104520022/
(1) 导入官方提供给的数据集(这里用MNIST)
def hello_world():
    from torchvision.datasets.mnist import MNIST
    from torchvision import transforms
    # transforms.Compose串联多个transforms操作
    transform = transforms.Compose(
        [
            transforms.ToTensor(),
            transforms.Normalize(mean=(0.5,), std=(0.5,))  # 均值和标准差
        ]
    )
    train_dataset = MNIST(root="./mnist_data", # 路径
                          train=True, # training set(True) or test set
                          transform=transform, # 上面transform的方法
                          target_transform=None, # 不转换标签
                          download=True) # 下载数据集
    index = 0
    print("train(train_dataset):{}".format(type(train_dataset[index])))
    print("train(train_dataset):{}[0]:{}".format(index, type(train_dataset[index][0])))
    print("train_dataset[{}][0].shape:{}".format(index, train_dataset[index][0].shape))
    print("len(train_dataset):{}".format(len(train_dataset)))
    print("type(train_dataset[{}][1]):{}".format(index, type(train_dataset[index][1])))
	return train_dataset
(2)有自己的图片,搭建自己的数据集

ImageFolder方法来搭建自己的数据集

def create_mydataset():
    from torchvision.datasets import ImageFolder
    from torchvision import transforms
    transform = transforms.Compose(
        [
            # 随机裁剪
            transforms.RandomResizedCrop(size=(224, 224)),
            # 随机水平翻转
            transforms.RandomHorizontalFlip(),
            transforms.ToTensor(),
            transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))
        ]
    )
	
    # 这里是训练集的地址
    train_dataset = ImageFolder(root=os.path.join(r"D:\yolo_B\images", "train"),
                                transform=transform, target_transform=None)

    index = 0
    print("train(train_dataset):{}".format(type(train_dataset[index])))
    print("train(train_dataset):{}[0]:{}".format(index, type(train_dataset[index][0])))
    print("train_dataset[{}][0].shape:{}".format(index, train_dataset[index][0].shape))
    print("len(train_dataset):{}".format(len(train_dataset)))
    print("type(train_dataset[{}][1]):{}".format(index, type(train_dataset[index][1])))
    # ImageFolder有一些属性 train_dataset.classes(值),train_dataset.class_to_idx(值与键)
    # train_dataset.classes:['blue', 'red']
    print("train_dataset.classes:{}".format(train_dataset.classes))          			     # train_dataset.class_to_idx:{'blue': 0, 'red': 1}
    print("train_dataset.class_to_idx:{}".format(train_dataset.class_to_idx))   

在这里插入图片描述

第三:dataloader

Dataloader也是一个类,datalodar把dataset分成一个对可迭代对象

就是对dataset进行划分,划分成一个个batch

然后之后的一系列操作都在这个可迭代对象上进行

def learn_dataloader():
    train_dataset = hello_world()
    from torch.utils.data import DataLoader
    train_loader = DataLoader(dataset=train_dataset,
                              batch_size=10000,
                              shuffle=False)
    # if shuffle = True则不同epoch之间的数据会被打乱

    from collections.abc import Iterable
    print("isinstance(train_dataset,Iteration):{}".\
          format(isinstance(train_dataset, Iterable)))
    print("isinstance(train_loader,Iteration):{}".\
          format(isinstance(train_loader, Iterable)))

    print("type(train_loader):{}".format(type(train_loader)))
    # loader的大小是batch的数量 dataset是总样本量的大小
    print("len(train_loader):{}".format(len(train_loader)))
    # batch 一个放着图片,一个放着label
    for batch in train_loader:
        print("type(batch):{}".format(type(batch)))
        print("len(batch):{}".format(len(batch)))
        print("type(batch[0]):{}".format(type(batch[0])))
        print("type(batch[0]):{}".format(type(batch[1])))
        print("type(batch[0]):{}".format(batch[0].shape))
        print("type(batch[0]):{}".format(batch[1].shape))
        break

📦python训练小技巧:
[enumerate 枚举](Python enumerate() 函数 | 菜鸟教程 (runoob.com))

def fun_way():
    train_dataset = hello_world()
    from torch.utils.data import DataLoader
    train_loader = DataLoader(dataset=train_dataset,
                              batch_size=10000,
                              shuffle=False)

    for batch,(x,y) in enumerate(train_loader):
        print("batch:{},type(x):{},type(y):{}".format(batch, type(x), type(y)))
        print("batch:{},x.shape:{},y.shape:{}".format(batch, x.shape, y.shape))
        break

tqdm 加进度条

def fun_way2():
    train_dataset = hello_world()
    from tqdm import tqdm
    from torch.utils.data import DataLoader
    train_loader = DataLoader(dataset=train_dataset,
                              batch_size=10000,
                              shuffle=False)

    with tqdm(train_loader, desc="TRAINING") as train_bar:
        for (x, y) in train_bar:
            pass

collate_fn 把标签也类型改变成torch.Tensor

def eg_1():
    train_dataset = hello_world()
    def collate_fn(batch):
        print("type(batch):{}".format(type(batch)))
        print("len(batch):{}".format(len(batch)))
        print("type(batch[0]):{}".format(type(batch[0])))
        x = [i[0] for i in batch]
        y = [i[1] for i in batch]
        x = torch.cat(x)[:, None, ...]
        y = torch.Tensor(y)
        return {"x":x, "y":y}

    from torch.utils.data import DataLoader
    train_loader =DataLoader(dataset=train_dataset,
                            batch_size=10000,
                            shuffle=False,
                            collate_fn=collate_fn)

    from torch.utils.data import DataLoader
    train_loader = DataLoader(dataset=train_dataset,
                              batch_size=10000,
                              shuffle=False,
                              collate_fn=collate_fn)

    for batch in train_loader:
        print("type(batch): {}".format(type(batch)))  # <class 'dict'>
        print("type(batch[\"x\"]): {}".format(type(batch["x"])))  # <class 'torch.Tensor'>
        print("type(batch[\"y\"]): {}".format(type(batch["y"])))  # <class 'torch.Tensor'>
        print("batch[\"x\"].shape: {}".format(batch["x"].shape))  # torch.Size([10000, 1, 28, 28])
        print("batch[\"y\"].shape: {}".format(batch["y"].shape))  # torch.Size([10000])
        break

第四:Module

所有的模型都必须继承基类,怎么查看model

  • 直接print(model)
  • 也可用model.named_parameters()
super(model,self).__init__的作用是调用父类的初始化,反正你想建立model就加上就好
model.__call__(x)=model(x) 两个方法一样 
model.__call__(x)里面也调用了model.forward(x)

模型调用和拉平

def eg_3():
    from torch import nn
    train_dataset = hello_world()

    class SimpleMode(nn.Module):
        def __init__(self):
            super(SimpleMode, self).__init__()
            self.conv1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=(1, 1))
            self.conv2 = nn.Conv2d(in_channels=3, out_channels=5, kernel_size=(1, 1))
            self.relu = nn.ReLU(inplace=True)
            # 从1开始拉平
            self.flatten = nn.Flatten(start_dim=1, end_dim=-1)  # (B, C, H ,W)
            self.linear = nn.Linear(in_features=5*28*28, out_features=10, bias=False)

        def forward(self, x):
            x = self.conv1(x)
            x = self.relu(x)
            x = self.conv2(x)
            x = self.relu(x)
            print("[before flatten x shape]:{}".format(x.shape))
            x = self.flatten(x)
            print("[after flatten x shape]:{}".format(x.shape))
            x = self.linear(x)
            x = self.relu(x)
            return x

    model = SimpleMode()
    x = train_dataset[0][0]
    x = x[None, ...]    # 增加一维 batch_size 的维度
    model(x)

model里面的方法

载入模型数据
方法一:
torch.load("./vgg16.pth", map_location = "cpu")
方法二:
from torch.nn import model_zoo
state_dict = model_zoo.load_url('数据网址')
保存模型数据
torch.save(模型,"路径") #保存了模型的参数

第五:optimizer优化器

用于调参

优化器的调用

    from torch import optim
    # 直接初始化随机梯度下降SGD类
    # lr 学习率 momentum 动量
    optimizer = optim.SGD(params=model.parameters(), lr=0.0001, momentum=0.9)
    print("optim.state_dict():{}".format(optimizer.state_dict()))

只调优部分参数

def eg_4():
    from torch import nn
    train_dataset = hello_world()

    class SimpleMode(nn.Module):
        def __init__(self):
            super(SimpleMode, self).__init__()
            self.conv1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=(1, 1))
            self.conv2 = nn.Conv2d(in_channels=3, out_channels=5, kernel_size=(1, 1))
            self.relu = nn.ReLU(inplace=True)
            # 从1开始拉平
            self.flatten = nn.Flatten(start_dim=1, end_dim=-1)  # (B, C, H ,W)
            self.linear = nn.Linear(in_features=5*28*28, out_features=10, bias=False)

        def forward(self, x):
            x = self.conv1(x)
            x = self.relu(x)
            x = self.conv2(x)
            x = self.relu(x)
            print("[before flatten x shape]:{}".format(x.shape))
            x = self.flatten(x)
            print("[after flatten x shape]:{}".format(x.shape))
            x = self.linear(x)
            x = self.relu(x)
            return x

    model = SimpleMode()
    x = train_dataset[0][0]
    x = x[None, ...]    # 增加一维 batch_size 的维度
    model(x)
    # 让网络只学习部分数据
    from torch import optim
    # 这里让只有bias为我们学习的
    params = [param for name, param in model.named_parameters() if ".bias" in name]
    optimizer = optim.SGD(params=params, lr=0.0001, momentum=0.9)
    print("optim.state_dict():{}".format(optimizer.state_dict()))

非常模式化的训练迭代步骤

def eg_5():
    from torch import nn
    train_dataset = hello_world()

    class SimpleMode(nn.Module):
        def __init__(self):
            super(SimpleMode, self).__init__()
            self.conv1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=(1, 1))
            self.conv2 = nn.Conv2d(in_channels=3, out_channels=5, kernel_size=(1, 1))
            self.relu = nn.ReLU(inplace=True)
            # 从1开始拉平
            self.flatten = nn.Flatten(start_dim=1, end_dim=-1)  # (B, C, H ,W)
            self.linear = nn.Linear(in_features=5 * 28 * 28, out_features=10, bias=False)

        def forward(self, x):
            x = self.conv1(x)
            x = self.relu(x)
            x = self.conv2(x)
            x = self.relu(x)
            print("[before flatten x shape]:{}".format(x.shape))
            x = self.flatten(x)
            print("[after flatten x shape]:{}".format(x.shape))
            x = self.linear(x)
            x = self.relu(x)
            return x

    model = SimpleMode()
    x = train_dataset[0][0]
    x = x[None, ...]  # 增加一维 batch_size 的维度
    model(x)
    from torch import optim
    from tqdm import tqdm
    optimizer = optim.SGD(params=model.parameters(), lr=0.001, momentum=0.9)
    loss_fn = nn.CrossEntropyLoss() # 一般用于多分类问题
    train_loader = learn_dataloader()

    for epoch in range(2):
        with tqdm(train_loader, desc="EPOCH:{}".format(epoch)) as train_bar:
            for (x, y) in train_bar:
                optimizer.zero_grad()
                loss = loss_fn(model(x), y)
                loss.backward()
                optimizer.step()
            print("epoch:{},loss:{:.6f}".format(epoch, loss))

整合

train

import os
from datetime import datetime
import torch
from torch import nn
from torch import optim
from torch.utils.data import Dataset, DataLoader
from torchvision import models, transforms
from torchvision.datasets.mnist import MNIST
from tqdm import tqdm

transform = transforms.Compose(
  [
    transforms.ToTensor(),
    transforms.Normalize(mean=(0.5,), std=(0.5,))
  ]
)
# dataset
train_dataset = MNIST(root="./mnist_data",
                      train=True,
                      transform=transform,
                      target_transform=None,
                      download=False)
# dataloader
train_loader = DataLoader(dataset=train_dataset,
                          batch_size=100,
                          shuffle=True)

class SimpleModel(nn.Module):
  def __init__(self):
      super(SimpleModel, self).__init__()
      self.conv1 = nn.Conv2d(in_channels=1, out_channels=3, kernel_size=(1, 1))
      self.conv2 = nn.Conv2d(in_channels=3, out_channels=5, kernel_size=(1, 1))
      self.relu = nn.ReLU(inplace=True)
      self.flatten = nn.Flatten(start_dim=1, end_dim=-1)
      self.linear = nn.Linear(in_features=5*28*28, out_features=10, bias=False)

  def forward(self, x):
      x = self.conv1(x)
      x = self.relu(x)
      x = self.conv2(x)
      x = self.relu(x)
      x = self.flatten(x)
      x = self.linear(x)
      x = self.relu(x)
      return x
# model
model = SimpleModel()
model.load_state_dict(torch.load("./model_2021_11_19.pth"))
# optimizer
optimizer = optim.SGD(params=model.parameters(), lr=0.001, momentum=0.9)
loss_fn = nn.CrossEntropyLoss()
# train
for epoch in range(2):
  with tqdm(train_loader, desc="EPOCH: {}".format(epoch)) as train_bar:
    for (x, y) in train_bar:
      optimizer.zero_grad()
      loss = loss_fn(model(x), y)
      loss.backward()
      optimizer.step()
  print("epoch: {},  loss: {:.6f}".format(epoch, loss))

time = str(datetime.now()).split(" ")[0].replace("-", "_")
torch.save(model.state_dict(), "model_{}.pth".format(time))

print("~~~~~~撒花~~~~~~")
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: VSCode是一款非常流行的开发工具,而PyTorch是一个用于深度学习的Python库。将这两者结合使用可以提供强大的深度学习开发环境。 VSCode提供了丰富的功能和插件,使得编码和调试过程更加高效。它具有智能的代码补全、语法高亮和错误检查功能,可以帮助开发者减少拼写错误和语法错误。此外,VSCode还具有强大的调试功能,可以跟踪代码的执行过程并查找错误。 PyTorch是一个用于构建神经网络和进行深度学习的库。它提供了丰富的高级和低级API,使得开发者可以以灵活的方式构建自己的神经网络模型。PyTorch还提供了自动求导功能,可以自动计算梯度并对模型进行优化。 在VSCode中使用PyTorch可以有以下好处: 1. 编写更加高效:VSCode的代码补全功能可以提供PyTorch中函数和类的建议,减少开发者在编写代码时的错误。 2. 调试更加方便:VSCode的调试功能可以帮助开发者在PyTorch模型运行过程中查找错误和调试代码,提高开发效率。 3. 丰富的插件支持:VSCode拥有大量与PyTorch相关的插件,可以增强开发者对深度学习模型的理解和调试能力。 总的来说,使用VSCode与PyTorch结合可以提供一个强大的深度学习开发环境,使得编码、调试和优化模型更加高效。 ### 回答2: VSCode是一款非常流行的跨平台代码编辑器,而PyTorch是一个广泛使用的机器学习框架,两者可以很好地结合起来提供代码编辑和深度学习的功能。 首先,作为一个代码编辑器,VSCode提供了丰富的功能和插件生态系统,可以满足开发者的需求。它具有智能代码补全、语法高亮、调试器、版本控制等功能,这些功能对于编写和调试代码非常有帮助。通过VSCode的插件系统,我们可以轻松地安装PyTorch相关的插件,提供对PyTorch代码的语法高亮、代码提示和自动补全等功能,使得编写PyTorch代码更加方便和高效。 其次,VSCode提供了一个交互式的开发环境,可以通过集成的终端运行Python脚本。这意味着我们可以在VSCode中直接运行PyTorch代码,调试和测试模型。VSCode还支持调试功能,可以通过设置断点、单步执行等方式来帮助我们查找和解决代码中的错误。这对于开发和调试深度学习模型非常有帮助,尤其是在调试模型的训练过程中。 另外,VSCode还提供了丰富的扩展库和集成工具,可以进一步增强PyTorch的功能。例如,我们可以使用VSCode的Git集成来管理代码的版本控制,使用远程开发插件在远程服务器上运行PyTorch代码,或者使用VSCode的Jupyter扩展来创建和运行Jupyter笔记本,进一步扩展PyTorch的应用场景。 总结来说,VSCode和PyTorch的结合能够提供一个完整且强大的开发环境,帮助开发者更加高效地编写、调试和管理PyTorch代码。无论是初学者还是经验丰富的研究人员,都可以从这个组合中获得便利和效率的提升。 ### 回答3: VSCode是一个非常流行的开源代码编辑器,而PyTorch是一个非常强大的深度学习框架。将它们结合使用可以为深度学习开发提供很多便利。 首先,VSCode提供了丰富的代码编辑功能,如智能代码补全、语法高亮、错误检查等。这些功能可以帮助开发者更快速地编写、调试和修改PyTorch代码,提高开发效率。 其次,VSCode还支持集成调试器。对于PyTorch的开发者来说,这是一个非常重要的功能。通过调试器,我们可以逐行地执行代码,观察变量的值,以及检查函数的执行过程。这对于调试复杂的神经网络模型和处理大量数据时尤其有用。 此外,VSCode还支持各种扩展和插件,可以进一步增强我们的PyTorch开发环境。例如,我们可以安装Python插件,以便在VSCode中运行和调试Python代码。我们还可以安装PyTorch相关的插件,如自动完成PyTorch的函数和类名,显示PyTorch文档等。 最后,VSCode还提供了版本控制的功能。我们可以使用Git等版本控制系统来跟踪、管理和协作开发PyTorch项目。VSCode内置了Git集成,可以方便地进行版本控制操作,如查看提交历史、分支管理等。 总之,使用VSCode来开发PyTorch项目可以提供更好的代码编辑体验、调试工具和版本控制功能。这些功能有助于提高开发效率、减少错误,并更好地管理和协作开发深度学习项目。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值