Day-29 Pytorch 还可以更轻松更简单!Pytorch Lightning

  • 我们整个系列带领大家从 Python 转移到 Pytorch 的撰写,我们在这个过程应该已经深刻体验 Framework 的威力了,但是!如果我告诉你,我们还可以更轻松,你相不相信?
  • 我们今天就来介绍一个 Open Source 计画,也就是 Pytorch Lightning ~

What is Pytorch Lightning

  • Pytorch 虽然足够便捷了,但是仍然存在一些底层 Framework 的硬伤,例如
    • model 状态属於 eval() or train()
    • device 要是 tpu, gpu, cpu
    • optimizer 的归零
    • ...
  • 可以发现小问题仍然非常非常多,这些东西在实验的过程和尝试的过程中,其实容易造成不必要的困扰,尤其当整体架构变得更加复杂时,这些细节往往容易影响到模型状态,却也容易造成不必要的实验困扰
  • 那 Pytorch Lightning 就顺应而生了,他提供了更加简洁的环境,提供了更加灵活的设备兼容,解决了不少 Pytorch 本身沉重且复杂的流程
  • 那由於是 open source project,因此我们可以在 pytorch lightning github 找到他们,也可以去看美美的官网

how to use it ?

  • 那要使用 Pytorch lightning 很简单,诚如他们网站所说,第一步是去安装,第二步就是开箱及用啦~
  • install
    • 视设备和环境使用 pip 或是其他方式下载,这边就不特别介绍了,可以自己去官网看看
  • 那实际使用我们就直接改写前面的模型来做为示范吧~

Rewrite Feed-Forward Neural Network

  • 我们就直接改写 Feed-Forward Neural Network 来作为一个示范
  • 那这边的改写顺序就依照官方文档的顺序改造
  • 首先基本的 import 要有之外,要记得多放 import pytorch_lightning as pl
    import numpy as np
    import pandas as pd
    
    import torch
    import torch.nn as nn
    from torch.utils.data import Dataset, DataLoader
    from torch.utils.data.sampler import SubsetRandomSampler
    
    import pytorch_lightning as pl
    
  • 依照文档的第一步,我们要把原本的模型宣告放上来,更改中间的 nn.Modulepl.LightningModule,那这样的改写不会影响到任何旧的撰写,原因是 pl.LightningModule 中有提供所有 nn.Module 中的所有 function,且多提供了 Lightning 会用的 function
    class FeedForwardNeuralNet(pl.LightningModule):
    
        def __init__(self, input_size, hidden_size, num_classes):
            super(FeedForwardNeuralNet, self).__init__()
            # define first layer
            self.l1 = nn.Linear(input_size, hidden_size)
            # activation function
            self.relu = nn.ReLU()
            # define second layer
            self.l2 = nn.Linear(hidden_size, num_classes)
    
        def forward(self, x):
            out = self.l1(x)
            out = self.relu(out)
            out = self.l2(out)
    
            return out
    
  • 那第二步骤是把原本写在外面的 optimizer 更改到里面的 configure_optimizers,所以我们会多一个
    def configure_optimizers(self, learning_rate):
        optimizer = torch.optim.Adam(self.parameters(), lr=learning_rate)
    
        return optimizer
    
  • 那接下来我们要把 train loop 也给写进去,但是这边要注意一件事情,Pytorch lightning 已经帮忙把大部分的事情全部做完了,因此我们写进来的只需要计算 loss 就可以了,因此会写成这样
    def training_step(self, batch, batch_idx):
        datas, labels = batch
        outputs = self(datas)
        loss = F.cross_entropy(outputs, labels)
    
        return loss
    
    • 那要特别注意,现在的 loss function 要利用 torch.nn.functional 套件的 functions
  • 所以到这里我们整个 class 会长成怎样?
    class FeedForwardNeuralNet(pl.LightningModule):
    
        def __init__(self, input_size, hidden_size, num_classes):
    
            super(FeedForwardNeuralNet, self).__init__()
            # define first layer
            self.l1 = nn.Linear(input_size, hidden_size)
            # activation function
            self.relu = nn.ReLU()
            # define second layer
            self.l2 = nn.Linear(hidden_size, num_classes)
    
        def forward(self, x):
    
            out = self.l1(x)
            out = self.relu(out)
            out = self.l2(out)
    
            return out
    
        def training_step(self, batch, batch_idx):
    
            datas, labels = batch
            outputs = self(datas)
            loss = F.cross_entropy(outputs, labels)
    
            return loss
    
        def configure_optimizers(self):
    
            optimizer = torch.optim.Adam(self.parameters(), lr=learning_rate)
    
            return optimizer
    
  • 那让我们使用看看我们改写的部分,在要使用 Pytorch Lightning System 需要 import 一个 Trainer
    from pytorch_lightning import Trainer
    
    trainer = Trainer()
    
  • 那我们一样取得训练资料,我们就一样拿手写资料集,所以我们的 Dataset 跟 Dataloader 会写成
    train_dataset = torchvision.datasets.MNIST(root='./data', 
                                               train=True,
                                               transform=transforms.ToTensor(), 
                                               download=False)
    train_loader = DataLoader(dataset=train_dataset, 
                              batch_size=batch_size,
                              shuffle=True)
    
  • 那训练操作就会是
    model = FeedForwardNeuralNet(input_size, hidden_size, num_classes)
    trainer = Trainer()
    trainer.fit(model, train_loader)
    
  • 这边要特别注意,Pytorch lightning 的 Trainer 会自动化
    • Epoch 跟 Batch size
    • Optimizer.step() 还有 backward, zero_grad()
    • 还有宣告 .eval() 或是 .train()
    • ...
      简单来说就是都帮你做好了
  • 那剩下还有验证跟测试等等部份的撰写,就请大家自己去官网理解了,官方文档写得非常非常清楚

每日小结

  • Pytorch Lightning 是一个能够让模型建立更加单纯的工具,高度自动化,高度轻量,大大的减少了建立模型上的困难
  • 但是为什麽不一开始就教学使用 pytorch lightning ? 可以发现 Pytorch Lightning 已经跳脱了很多基础架构的东西了,结构也有了明显的变化,甚至撰写的逻辑也不同了,因此对於初学没有太大的帮助,只是在有基础概念之後,可以发现 Pytorch lightning 可以减少更多问题,因此在这里提出
  • 到这里,我们已经把所有 Pytorch 需要知道的东西都学完了~ 恭喜大家~

<<:  [Day30]程序菜鸟自学C++资料结构演算法 – 心得总结

>>:  Day-30 不完美收工

Emlog Pro 去除商店限制/未注册提示

emlog是完全开源的软件,但编写,支持和分发仍然需要花费很多时间和费用。投我以桃,报之以李,作为付...

Leetcode 挑战 Day 13 [13. Roman to Integer]

13. Roman to Integer 今天我们一起挑战leetcode第13题Roman to ...

DAY 3 新增 Git 来为版本进行管控

为什麽要用 git Git 是一个好用的分散式版本控管软件,在我们要开始写 html 之前,推荐要先...

M55是第一个支援v8.1-M架构的M系列处理器!!

根据ARM官方的介绍,M55是第一个支援v8.1-M架构的M系列处理器。而M系列主要是针对对於成本和...

Android Studio初学笔记-Day13-ScrollView

ScrollView 今天要介绍的元件,当介面的内容开始变多时就派上用场了,毕竟手机萤幕或着各类3c...