PyTorch Lightning: 데이터 모듈, 콜백, TPU 및 레코더
When I was a young man,
I had liberty but I didn’t see it,
I had time but I didn’t know it,
And I had PyTorch Lightning but I didn't use it.
- Newbie PyTorch User
또 다른 블로그, 또 하나의 위대한 비디오 게임 인용이 이들에게 학살당했다.어쨌든 내가 PyTorch를 사용하기 시작했을 때 질투나는 것은 Tensorflow가 모델의 성능을 감시하는 데 이렇게 많은 지원을 한다는 것이다.내 말은 Tensorflow의 초보자가 지나가기만 하고 모골이 송연할 때, 나는 여분의 절차로 훈련 순환을 작성해야 한다는 것이다.
그래서 나는 대부분의 PyTorch 초보들처럼 근육 기억이 될 때까지 훈련 순환 코드를 배우고 작성하는 것이 네가 해서는 안 될 일이다.이 점에 대한 몇 가지 조언은 왜 한 걸음 한 걸음 효과가 있는지 이해하는 것이다. 네가 해내면 한 줄 코드가 의미가 생기기 시작한다. 나를 믿어라. 내가 해내면 다시는 그것을 잊지 않을 것이다.
주제로 돌아가서, 내가 PyTorch를 좋아하는 점은, 내가 그것을 어느 정도 사용자 정의할 수 있는지, 그리고 디버깅이 얼마나 쉬운지.그러나 만약 내가 어떤 방식으로 이 기능들을 보존하고 군더더기를 줄일 수 있다면 더욱 좋겠다.
자, 네가 그것을 가지게 되면 해결 방안은 PyTorch Lightning이다. 내 말은 이렇게 멋진 이름을 가진 사람은 누구나 위대한 사람이 될 운명이다. 그러나 이 때문에 너를 설득할 수 없다면 본문이 끝날 때 너는 위대한 사람이 되기를 바란다.
그리고 번개에 대해 기본적으로 알고 있다면 실제로는 더 좋을 것이다.만약 네가 그것의 기본 지식을 알고 싶다면, 내가 얼마 전에 쓴 이 문장Training Neural Networks using PyTorch Lighting을 시험해 보아라.
데이터 세트, 데이터 로더 및 데이터 모듈
생활 속에서 두 가지가 만족스럽다. 첫 번째는 초보자인Vim 사용자가 Vim에서 탈퇴를 시도하는 것을 보는 것이고, 두 번째는 초보자인PyTorch 사용자가 사용자 정의 데이터를 위해 데이터 로더를 만드는 것을 보는 것이다.Dataset이라는 강력한 유틸리티를 사용하여 PyTorch에서 데이터 로더를 만드는 방법을 살펴보겠습니다.
데이터 세트 클래스
Pytork를 배우고 있다면 가장 중요한 것은 데이터 로더를 만드는 것입니다. 많은 방법이 있습니다. 그림에 대해서는 torchvision에 ImageFolder 유틸리티가 있고 텍스트 데이터에 대해서는 BucketIterator가 있습니다. 거짓말을 하지 않습니다. 아주 편리합니다. 그러나 로더된 데이터가 필요한 형식이 아니라면 어떻게 해야 합니까?이 경우 Dataset 클래스를 사용할 수 있습니다. 제가 Dataset 클래스를 좋아하는 것 뿐만 아니라 상상할 수 없을 정도로 맞춤형으로 만들 수 있습니다.
Dataset 클래스에서 다음 세 가지 주요 함수를 정의해야 합니다. -
import torch
from sklearn.datasets import make_classification
from torch.utils.data import Dataset
class TabularData(Dataset):
def __init__(self, X, Y, train = True):
self.X = X
self.Y = Y
def __len__(self):
return len(self.X)
def __getitem__(self, idx):
features = self.X[idx]
if self.Y is not None:
target = self.Y[idx]
return {
'X' : torch.tensor(features, dtype = torch.float32),
'Y' : torch.tensor(target, dtype = torch.long)
}
else:
return {
'X' : torch.tensor(features, dtype = torch.float32)
}
X, Y = make_classification()
train_data = TabularData(X, Y)
train_data[0]
출력: -{'X': tensor([ 1.1018, -0.0042, 2.1382, -0.7926, -0.6016, 1.5499, -0.4010, 0.3327,
0.1973, -1.3655, 0.4870, 0.7568, -0.7460, -0.8977, 0.1395, 0.0814,
-1.4849, -0.2000, 1.2643, 0.4178]), 'Y': tensor(1)}
스바라시!이것은 옳은 것 같다. 만약 당신이 클래스의 출력을 약간 바꾸고 결과를 검사한다면, 당신은 어떤 일이 일어날지 시험하고 실험할 수 있다.그러나 이 강좌에서 우리는 패션 MNIST 데이터를 연구할 것이다. 고맙게도 torchvision에 이미 하나의 데이터 집합이 있기 때문에 우리는 그것을 불러올 것이다.from torchvision import datasets, transforms
transform = transforms.Compose([
transforms.ToTensor()
])
train = datasets.FashionMNIST('',train = True, download = True, transform=transform)
test = datasets.FashionMNIST('',train = False, download = True, transform=transform)
이제 데이터가 생겼으니 데이터 마운트기로 옮길 때가 되었다.데이터 로더
DataLoader는 데이터 세트의 입력을 가져와 그 중의 데이터를 일괄적으로 포장하고 교체기를 만들어서 이 일괄을 교체합니다.이러한 요소들은 전체 배치 프로세스를 더욱 쉽게 하는 동시에 최대한의 사용자 정의성을 유지합니다.내 말은, 너는 자신의 대조표를 작성해서 데이터를 대량으로 처리하는 방법을 정의할 수 있다는 것이다. 너는 또 무엇을 원하느냐?
데이터세트 클래스를 만드는 방법을 보았습니다. 데이터Loader를 만들려면 데이터세트 실례를 데이터Loader에 전달하면 됩니다.위에서 작성한 MNIST 데이터 세트에 대해 이 작업을 수행하고 출력을 확인하는 방법을 살펴보겠습니다.
import matplotlib.pyplot as plt
from torch.utils.data import DataLoader
trainloader = DataLoader(train, batch_size= 32, shuffle=True)
testloader = DataLoader(test, batch_size= 32, shuffle=True)
#Plotting a Batch of DataLoader
images, labels = iter(trainloader).next()
plt.figure(figsize = (12,16))
for e,(img, lbl) in enumerate(zip(images, labels)):
plt.subplot(8,4,e+1)
plt.imshow(img[0])
plt.title(f'Class: {lbl.item()}')
plt.subplots_adjust(hspace=0.6)
출력: -빌어먹을, 예쁘고 정확해 보여. 자, 우리 데이터 캐리어가 정상적으로 작동하는 것 같아.하지만 이건 내 문제야, 아니면 너무 혼란스러워 보여?내 말은 우리가 데이터에 대해 일괄 처리를 했다는 것이다. 이것은 매우 좋지만, 변수는 어디에도 없는 것 같고, 조직이 많지 않은 것 같다.이것은 기본적으로 데이터 모듈이 쓸모가 있는 곳이다😎.
데이터 모듈
DataModule은 DataLoader와 데이터 처리에 필요한 절차를 봉인하여 다시 사용할 수 있고 공유할 수 있는 클래스입니다.데이터 로더를 만드는 것은 혼란스러울 수 있습니다. 이것이 바로 DataModule 형식으로 데이터 집합을 조합하는 것이 가장 좋은 이유입니다.DataModule 에는 다음과 같이 DataModule 형식을 정의해야 하는 몇 가지 방법이 있습니다.
import pytorch-lightning as pl
class DataModuleClass(pl.LightningDataModule):
def __init__(self):
# Define class attributs here
def prepare_data(self):
# Define steps that should be done
# on only one GPU, like getting data.
def setup(self, stage=None):
# Define steps that should be done on
# every GPU, like splitting data, applying
# transform etc.
def train_dataloader(self):
# Stage DataLoader for Training Data
def val_dataloader(self):
# Stage DataLoader for Validation Data
def test_dataloader(self):
# Stage DataLoader for Testing Data
이것은 보기에 매우 좋기 때문에, 우리는 계속해서 우리의 패션 MNIST 데이터에 DataModule을 만들 것이다.import pytorch_lightning as pl
class DataModuleFashionMNIST(pl.LightningDataModule):
def __init__(self):
super().__init__()
self.dir = ''
self.batch_size = 32
self.transform = transforms.Compose([
transforms.ToTensor()
])
def prepare_data(self):
datasets.FashionMNIST(self.dir, train = True, download = True)
datasets.FashionMNIST(self.dir, train = False, download = True)
def setup(self, stage=None):
data = datasets.FashionMNIST(self.dir,
train = True,
transform = self.transform)
self.train, self.valid = random_split(data, [52000, 8000])
self.test = datasets.FashionMNIST(self.download_dir,
train = False,
transform = self.transform)
def train_dataloader(self):
return DataLoader(self.train, batch_size = self.batch_size)
def val_dataloader(self):
return DataLoader(self.valid, batch_size = self.batch_size)
def test_dataloader(self):
return DataLoader(self.test_data, batch_size = self.batch_size)
data = DataModuleFashionMNIST()
좋습니다. 기본적으로 그렇습니다. 하지만 그것에 대해 깊이 있게 설명하고 싶다면 this article 제가 쓴 데이터 모듈에 대한 설명을 참고하십시오.플래시 콜백 및 고리
리셋은 기본적으로 필요할 때 실행되는 코드를 포함하는 프로그램이다.콜백 시기와 무엇을 해야 하는지는 콜백 연결 고리를 사용하여 정의됩니다. 그 중 일부는 epoch end, validation epoch end 등입니다. 도량을 감시하고 모델을 저장하거나 다른 멋진 것들을 저장할 논리를 정의할 수 있습니다.만약 내가 리셋을 하나의 모인으로 정의해야 한다면, 그것은 다음과 같다.
이것은 훈련에 매우 필요하지만, 다른 것들에는 매우 유용하다.여러 가지 중요한 임무에 사용할 수 있는 내장된 리셋이 많다.그중 일부는 -
반송
묘사
앞당겨 멈추다
개선을 멈출 때 훈련을 멈추는 지표를 감시하다.
학습률 모니터
훈련 기간에 학습률 스케줄러의 학습률을 자동으로 감시하고 기록한다.
모델 체크포인트
수량을 모니터링하여 모델을 주기적으로 저장합니다.
반송
사용자 정의 리셋을 정의하는 기본 클래스입니다.
새끼양의 등
기본적으로 콜백의 Lambda 함수다.
본문에서, 우리는 앞의 두 가지를 사용하지만, 당신은 문서를 참고하여 더 많은 정보를 얻을 수 있습니다.Lightning 웹 사이트의 동영상 튜토리얼은 매우 좋다.
TPU-Hulkified GPU?
TPU는 기계 학습 임무를 가속화하는 가속기이다.문제는 플랫폼, 즉 TensorFlow에 의존한다는 것이다.TPU는 주로 Tensorflow를 대상으로 최적화를 했는데 이것은 매우 이기적이라고 생각합니다. 왜냐하면 PyTorch가 너무 좋기 때문입니다.
그러나 우리는 데이터 로더에서 TPU 샘플러를 제작하고 전달하는 방법으로 파이토크에서 그것을 사용할 수 있다.장치 종류를 xm로 바꿔야 합니다. 이것은 매우 번거로운 작업입니다.xla device () 는 PyTorch/xla를 설치해서 모든 것을 완성하는 것이 아니라 optimizer에 두 가지 추가 절차를 추가합니다.일은 이렇다. -
import torch_xla.core.xla_model as xm
dev = xm.xla_device()
# TPU sampler
data_sampler = torch.utils.data.distributed.DistributedSampler(
dataset,
num_replicas=xm.xrt_world_size(),
rank=xm.get_ordinal())
dataloader = DataLoader(dataset, batch_size=32, sampler = data_sampler)
# Training loop
for batch in dataloader:
...
xm.optimizer_step(optimizer)
xm.mark_step()
...
위의 코드는 엉망진창이지만, Lightning에서는 이 모든 것을 한 줄로 간소화한다.당신이 해야 할 일은 tpu 핵심의 수량을 당신에게 전달하는 것입니다. 당신은 하루의 임무를 완성할 수 있습니다.정말 간단해.trainer = pl.Trainer(tpu_cores = 1)
trainer.fit(model)
내 말은, 이건 정말 더 이상 간단할 수 없는 일이지만, 한 가지 더 할 말이 있다. 바로 벌목꾼이다.어디 보자.벌목공
Logger는 지표, 슈퍼 파라미터, 그리고 더 멋진 것을 감시하는 실용적인 도구이다.사실, 너는 이미 시험해 보았을지도 몰라, 장력판.들어보셨어요?만약 네가 여기에 있다면, 너는 매우 가능성이 있다.Tensorboard 외에 PyTorch Lightning은 권중과 편차,Comet에서 온 각종 제3자 기록기를 지원한다.ml, MlFlow 등.
실제로 Lightning에서는 여러 레코더를 동시에 사용할 수 있습니다.레코더를 사용하려면 트레이너 클래스의logger 매개 변수 아래 단독으로 레코더 목록으로 전달할 수 있습니다.
from pytorch_lightning.loggers import WandbLogger
# Single Logger
wandb_logger = WandbLogger(project='Fashion MNIST', log_model='all')
trainer = Trainer(logger=wandb_logger)
# Multiple Loggers
from pytorch_lightning.loggers import TensorBoardLogger
tb_logger = TensorBoardLogger('tb_logs', name='my_model')
trainer = Trainer(logger=[wandb_logger, tb_logger])
관건은 어떻게 이 값들을 기록합니까?우리는 위에서 언급한 모든 내용을 응용하는 동시에 이 점을 어떻게 하는지 볼 것이다.이 모든 것을 함께 놓아라
모델의 구성 부분은 귀하가 제공한 데이터입니다. 본고에서 데이터 모듈을 논의했기 때문에 먼저 유행이 지난 MNIST 데이터에 데이터 모듈을 만듭니다.
import pytorch_lightning as pl
from torchvision import datasets, transforms
class DataModuleFashionMNIST(pl.LightningDataModule):
def __init__(self, batch_size = 32):
super().__init__()
self.dir = ''
self.batch_size = batch_size
self.transform = transforms.Compose([
transforms.ToTensor()
])
def prepare_data(self):
datasets.FashionMNIST(self.dir, train = True, download = True)
datasets.FashionMNIST(self.dir, train = False, download = True)
def setup(self, stage=None):
data = datasets.FashionMNIST(self.dir,
train = True,
transform = self.transform)
self.train, self.valid = random_split(data, [52000, 8000])
self.test = datasets.FashionMNIST(self.download_dir,
train = False,
transform = self.transform)
def train_dataloader(self):
return DataLoader(self.train, batch_size = self.batch_size)
def val_dataloader(self):
return DataLoader(self.valid, batch_size = self.batch_size)
def test_dataloader(self):
return DataLoader(self.test_data, batch_size = self.batch_size)
data = DataModuleFashionMNIST()
이제 WandbLogger에 대한 모델 클래스 및 설정 로그를 생성하고 모델 인스턴스를 생성합니다.from torch import nn, optim
import torch.nn.functional as F
class FashionMNISTModel(pl.LightningModule):
def __init__(self):
super().__init__()
# 28 * 28 * 3
self.conv1 = nn.Conv2d(1,16, stride = 1, padding = 1, kernel_size = 3)
# 14 * 14 * 16
self.conv2 = nn.Conv2d(16,32, stride = 1, padding = 1, kernel_size = 3)
# 7 * 7 * 32
self.conv3 = nn.Conv2d(32,64, stride = 1, padding = 1, kernel_size = 3)
# 3 * 3 * 64
self.fc1 = nn.Linear(3*3*64,128)
self.fc2 = nn.Linear(128,64)
self.out = nn.Linear(64,10)
self.pool = nn.MaxPool2d(2,2)
self.loss = nn.CrossEntropyLoss()
def forward(self,x):
x = F.relu(self.pool(self.conv1(x)))
x = F.relu(self.pool(self.conv2(x)))
x = F.relu(self.pool(self.conv3(x)))
batch_size, _, _, _ = x.size()
x = x.view(batch_size,-1)
x = F.relu(self.fc1(x))
x = F.relu(self.fc2(x))
return self.out(x)
def configure_optimizers(self):
return optim.Adam(self.parameters())
def training_step(self, train_batch, batch_idx):
x, y = train_batch
logits = self.forward(x)
loss = self.loss(logits,y)
# Logging the loss
self.log('train/loss', loss, on_epoch=True)
return loss
def validation_step(self, valid_batch, batch_idx):
x, y = valid_batch
logits = self.forward(x)
loss = self.loss(logits,y)
# Logging the loss
self.log('valid/loss', loss, on_epoch=True)
return loss
위의 코드에서 보듯이, 우리는 self를 사용합니다.log () 는 우리가 생성할 손실치 도표를 기록합니다.이제 레코더를 만들고 트레이너를 설치합시다.from pytorch_lightning.loggers import WandbLogger
model = FashionMNISTModel()
wandb_logger = WandbLogger(project='Fashion MNIST', log_model='all')
trainer = pl.Trainer(max_epochs=10, tpu_cores = 1, logger = wandb_logger)
wandb_logger.watch(model)
trainer.fit(model, data)
상기 코드를 실행하면 실행할 때 로그를 그립니다.나는 self로 손실치를 그리고 있다.log () 와watch () 를 사용하여 사다리를 기록합니다.
구성 오류 예외가 발생하면 TPU 장치를 찾을 수 없습니다.다음 명령을 실행하여 복구합니다.
%%capture
!curl https://raw.githubusercontent.com/pytorch/xla/master/contrib/scripts/env-setup.py -o pytorch-xla-env-setup.py > /dev/null
!python pytorch-xla-env-setup.py --version nightly --apt-packages libomp5 libopenblas-dev > /dev/null
!pip install pytorch-lightning > /dev/null
모형이 매우 간단하기 때문에, 나는 어떤 리셋도 사용하지 않았지만, 당신이 원한다면 사용할 수 있습니다.Learning Rate Monitor Callback에서는 스케줄러가 작동하고 Checkpoint Callback에서 Callback 대신 모델 체크포인트 Callback을 전달해야 합니다.나부터 너까지...
와, 그것은 감동적인 여정인 것 같아.솔직히 말해서 나는 번개가 매우 멋있는 것이 많다고 생각한다. 한 사람이 이 사실을 이용할 수 있고, 우리는 이 모든 것을 사용할 수 있으며, 동시에 번개가 PyTorch에 접근하는 것을 유지하여 그것이 얼마나 강한지 증명할 수 있다.나는 너희들이 지금 번개가 매우 좋은 학습과 사용 도구라고 믿기를 바란다.
Reference
이 문제에 관하여(PyTorch Lightning: 데이터 모듈, 콜백, TPU 및 레코더), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/krypticmouse/pytorch-lightning-datamodules-callbacks-tpu-and-loggers-4nhb텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)