Pytorch Lightning使用指南

59 篇文章 4 订阅
46 篇文章 3 订阅


在这里插入图片描述
在这里插入图片描述
感谢:Pytorch Lightning 完全攻略!一文
[入门]PyTorch Lightning快速上手-1 https://zhuanlan.zhihu.com/p/120331610

地址送上:
https://github.com/PyTorchLightning/pytorch-lightning
https://pytorch-lightning.readthedocs.io/en/latest/

1.写在前面

使用Lightning的好处

  • 只需要专注于研究代码

不需要写一大堆的 .cuda() 和 .to(device),Lightning会帮你自动处理。如果要新建一个tensor,可以使用type_as来使得新tensor处于相同的处理器上。Pytorch-Lighting 的一大特点是把模型和系统分开来看。模型是像Resnet18, RNN之类的纯模型, 而系统定义了一组模型如何相互交互,如GAN(生成器网络与判别器网络)、Seq2Seq(Encoder与Decoder网络)和Bert。同时,有时候问题只涉及一个模型,那么这个系统则可以是一个通用的系统,用于描述模型如何使用,并可以被复用到很多其他项目。Pytorch-Lighting 的核心设计思想是“自给自足”。每个网络也同时包含了如何训练、如何测试、优化器定义等内容。

  • 工程代码参数化

平时我们写模型训练的时候,这部分代码会不断重复,但又不得不做,不如说ealy stopping,精度的调整,显存内存之间的数据转移。这部分代码虽然不难,但减少这部分代码会使得 研究代码 更加清晰,整体也更加简洁。

2.使用步骤

  • Step 1: Add these imports
import os
import torch
from torch import nn
import torch.nn.functional as F
from torchvision.datasets import MNIST
from torch.utils.data import DataLoader, random_split
from torchvision import transforms
import pytorch_lightning as pl
  • Step 2: Define a LightningModule (nn.Module subclass)
class LitAutoEncoder(pl.LightningModule):
    def __init__(self):
        super().__init__()
        self.encoder = nn.Sequential(nn.Linear(28 * 28, 128), nn.ReLU(), nn.Linear(128, 3))
        self.decoder = nn.Sequential(nn.Linear(3, 128), nn.ReLU(), nn.Linear(128, 28 * 28))

    def forward(self, x):
        # in lightning, forward defines the prediction/inference actions
        embedding = self.encoder(x)
        return embedding

    def training_step(self, batch, batch_idx):
        # training_step defines the train loop. It is independent of forward
        x, y = batch
        x = x.view(x.size(0), -1)
        z = self.encoder(x)
        x_hat = self.decoder(z)
        loss = F.mse_loss(x_hat, x)
        self.log("train_loss", loss)
        return loss

    def configure_optimizers(self):
        optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)
        return optimizer
  • Step 3: Train!
dataset = MNIST(os.getcwd(), download=True, transform=transforms.ToTensor())
train, val = random_split(dataset, [55000, 5000])

autoencoder = LitAutoEncoder()
trainer = pl.Trainer()
trainer.fit(autoencoder, DataLoader(train), DataLoader(val))

3.高级特征

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • Pro-level control of training loops (advanced users)
class LitAutoEncoder(pl.LightningModule):
    def __init__(self):
        super().__init__()
        self.automatic_optimization = False

    def training_step(self, batch, batch_idx):
        # access your optimizers with use_pl_optimizer=False. Default is True
        opt_a, opt_b = self.optimizers(use_pl_optimizer=True)

        loss_a = ...
        self.manual_backward(loss_a, opt_a)
        opt_a.step()
        opt_a.zero_grad()

        loss_b = ...
        self.manual_backward(loss_b, opt_b, retain_graph=True)
        self.manual_backward(loss_b, opt_b)
        opt_b.step()
        opt_b.zero_grad()
  • Advantages over unstructured PyTorch

Models become hardware agnostic
Code is clear to read because engineering code is abstracted away
Easier to reproduce
Make fewer mistakes because lightning handles the tricky engineering
Keeps all the flexibility (LightningModules are still PyTorch modules), but removes a ton of boilerplate
Lightning has dozens of integrations with popular machine learning tools.
Tested rigorously with every new PR. We test every combination of PyTorch and Python supported versions, every OS, multi GPUs and even TPUs.
Minimal running speed overhead (about 300 ms per epoch compared with pure PyTorch).

4.一些使用tips

Pytorch-Lightning 是一个很好的库,或者说是pytorch的抽象和包装。它的好处是可复用性强,易维护,逻辑清晰等。缺点也很明显,这个包需要学习和理解的内容还是挺多的,或者换句话说,很重。如果直接按照官方的模板写代码,小型project还好,如果是大型项目,有复数个需要调试验证的模型和数据集,那就不太好办,甚至更加麻烦了。经过几天的摸索和调试,我总结出了下面这样一套好用的模板,也可以说是对Pytorch-Lightning的进一步抽象。

欢迎大家尝试这一套代码风格,如果用习惯的话还是相当方便复用的,也不容易半道退坑。
在这里插入图片描述
完全版模板可以在GitHub:https://github.com/miracleyoo/pytorch-lightning-template 找到。

5.Saving

ModelCheckpoint 地址: https://pytorch-lightning.readthedocs.io/en/latest/extensions/generated/pytorch_lightning.callbacks.ModelCheckpoint.html%23pytorch_lightning.callbacks.ModelCheckpoint

ModelCheckpoint: 自动储存的callback module。默认情况下training过程中只会自动储存最新的模型与相关参数,而用户可以通过这个module自定义。如观测一个val_loss的量,并储存top 3好的模型,且同时储存最后一个epoch的模型,等等。例:

from pytorch_lightning.callbacks import ModelCheckpoint

# saves a file like: my/path/sample-mnist-epoch=02-val_loss=0.32.ckpt
checkpoint_callback = ModelCheckpoint(
    monitor='val_loss',
    filename='sample-mnist-{epoch:02d}-{val_loss:.2f}',
    save_top_k=3,
    mode='min',
    save_last=True
)

trainer = pl.Trainer(gpus=1, max_epochs=3, progress_bar_refresh_rate=20, callbacks=[checkpoint_callback])
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这段代码实现了一个将点云数据分割成体素格子的过程,并计算每个格子内的特征的和。 具体来说,输入参数 `x` 是一个形状为 $(N, C)$ 的特征矩阵,其中 $N$ 表示点云中点的数量,$C$ 表示每个点的特征维度。输入参数 `geometry` 是一个形状为 $(N, 3)$ 的位置矩阵,其中每一行表示一个点的位置,三个元素分别表示 $x$、$y$、$z$ 坐标。输入参数 `ranks` 是一个形状为 $(N,)$ 的整数数组,表示每个点所在的体素格子的编号。 首先,代码通过 `cumsum` 方法对特征矩阵 `x` 进行累加,得到一个新的特征矩阵 `x`,使得 `x[i]` 表示前 $i$ 个点的特征的累加和。然后,代码根据 `ranks` 数组中的变化情况(即相邻元素是否相等),将 `x` 和 `geometry` 矩阵中相应的行筛选出来。这里使用了一个 `mask` 数组,将需要保留的行对应的元素设为 `True`,其余行对应的元素设为 `False`。接着,代码通过 `cat` 方法将 `x` 的第一行和剩余行的差值按行拼接起来,得到一个新的特征矩阵 `x`,使得 `x[i]` 表示第 $i$ 个体素格子内所有点的特征的和。 举个例子,假设我们有一个点云数据集,其中包含 $N=10$ 个点,每个点的特征维度为 $C=3$,坐标范围为 $[0,1]$,分割成 $M=2$ 个体素格子。我们可以将每个点的坐标映射到相应的格子中,得到一个形状为 $(N, 3)$ 的 `geometry` 矩阵,其中前 $5$ 行表示第一个格子内的点的坐标,后 $5$ 行表示第二个格子内的点的坐标。我们可以随机生成一个形状为 $(N, C)$ 的特征矩阵 `x`,例如使用以下代码: ```python import torch torch.manual_seed(0) x = torch.rand(N, C) ``` 此时 `x` 和 `geometry` 矩阵可能如下所示: ``` x geometry [[0.5488, 0.7152, 0.6028], [0.5449, 0.4237, 0.6459], ...] # 第一个格子 [[0.8918, 0.9637, 0.3834], [0.7917, 0.5289, 0.568], ...] # 第二个格子 ``` 假设我们将第一个格子的编号设为 $0$,第二个格子的编号设为 $1$,则 `ranks` 数组可能如下所示: ``` ranks [0, 0, 0, 0, 0, 1, 1, 1, 1, 1] ``` 代码将 `x` 和 `geometry` 矩阵输入到 `forward` 方法中,得到一个形状为 $(M, C)$ 的输出矩阵 `x`,例如使用以下代码: ```python bev = BEV(voxel_size=0.5, start_position=0.0) output = bev(x, geometry, ranks) ``` 此时 `output` 矩阵可能如下所示: ``` output [[2.9817, 3.3458, 2.9297], [2.2329, 2.4926, 2.7721]] # 两个格子内的特征和 ``` 其中第一行表示第一个格子内所有点的特征的和,第二行表示第二个格子内所有点的特征的和。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值