OneBook(Python & Deep Learning)
  • 한곳에서 끝내는 파이썬 & 머신러닝 & 딥러닝
  • 문서 작업을 시작하며
  • 1. 인공지능(Artificial Intelligence) 시대
    • 1.1. 인공지능이란 도대체 무엇인가?
    • 1.2. 4차 산업혁명
    • 1.3. 인공지능의 역사
    • 1.4. 인공지능 > 머신러닝 > 딥러닝
    • 1.5. 머신러닝
    • 1.6. 머신러닝 알고리즘
      • 1.6.1. 지도 학습 (Supervised Learning)
      • 1.6.2. 비지도 학습 (Unsupervised learning)
      • 1.6.3. 강화 학습(Reinforcement Learning)
    • 1.7. 인공신경망(ANN)
    • 1.8. 딥러닝
  • 2. 기본 상식
    • 2.1. 기본 용어의 이해
      • 2.1.1. CPU와 GPU의 차이
      • 2.1.2. 오픈소스(Open Source)
      • 2.1.3. 깃허브(GitHub)
      • 2.1.4. 위키 Wiki
      • 2.1.5. 아나콘다(Anaconda)
      • 2.1.6. 활성화 함수
      • 2.1.5. 딥러닝 프레임워크 소개
    • 2.2. 텐서플로(Tensorflow)
    • 2.3. 케라스(Keras)
    • 2.4. 파이토치(PyTorch)
    • 2.5. 학습에 필요한 중요한 도구와 라이브러리들
      • 2.5.1. 주피터 노트북(Jupyter Notebook)
      • 2.5.2. 파이참(PyCharm)
      • 2.5.3. 스파이더(Spyder)
      • 2.5.4. 넘파이(NumPy)
      • 2.5.5. 싸이파이(SciPy)
      • 2.5.6. Matplotlib
      • 2.5.7. 판다스(Pandas)
      • 2.5.8. 장고(Django)
      • 2.5.9. 파이큐티(pyQT)
      • 2.5.10. 싸이킷런(Scikit-learn)(Sklearn)
      • 2.5.11. CUDA & cuDNN
      • 2.5.12. 파이썬 표준 내장 라이브러리
    • 2.6. AI공부에 필요한 기본지식 3가지
      • 2.6.1. 수학
      • 2.6.2. 프로그래밍 기술
      • 2.6.3. AI의 적용 대상 산업에 대한 지식
  • 3. 개발 환경설정
    • 3.1. 윈도우 환경에서 설치하기
      • 3.1.1. 아나콘다 설치 (파이썬 설치)
        • 1) 아나콘다 패키지 업데이트
        • 2) conda에서 파이썬 가상 환경 (virtual environments) 생성하기
        • 3) NVIDIA GPU 환경 설정하기
      • 3.1.2. 텐서플로 설치
      • 3.1.3. 케라스 설치
      • 3.1.4. Jupyter Notebook 설치
      • 3.1.5. Visual Studio Code 설치
      • 3.1.6. 파이참 설치
        • 1) 파이참 가상환경 설정
        • 2) 파이참 환경 설정
        • 3) 설치된 라이브러리들의 버전 확인 하기
    • 3.2. 리눅스 환경에서 설치하기
      • 3.2.1. 아나콘다 설치(파이썬 설치)
      • 3.2.2. 텐서플로 설치
      • 3.2.3. 케라스 설치
      • 3.2.4. 장고 설치
      • 3.2.5. 파이참(PyCharm) 설치
        • 1) 파이참 가상환경 설정
  • 4. 파이썬 기초 학습
    • 4.1. 파이썬(Python)
    • 4.2. 파이썬의 특징
    • 4.3. 파이썬 기본 문법
      • 4.3.1. 대화형과 스크립트 모드 프로그래밍
      • 4.3.2. 모듈의 사용(import)
      • 4.3.3. 파이썬 식별자(Identifiers)
      • 4.3.4. 예약어(Reserved Words)
      • 4.3.5. 행(Lines)과 들여쓰기(Indentation)
      • 4.3.6. 문자열 표시
      • 4.3.7. 주석
      • 4.3.8. 파이썬 변수(Variables)
    • 4.4. 자료형과 연산자
      • 4.4.1. 자료형
      • 4.4.2. 파이썬 연산자
    • 4.5. 조건문과 반복문
      • 4.5.1. 조건문
      • 4.5.2. 반복문
    • 4.6. 함수
      • 4.6.1. 함수의 종류
    • 4.7. 모듈(Modules)
      • 4.7.1. 모듈의 참조 위치
      • 4.7.2. 네임스페이스(Namespace)와 범위(Scoping)
      • 4.7.3. dir( ) 함수
      • 4.7.4. 패키지(Packages)
      • 4.7.5. 기본 내장 모듈
    • 4.8. 숫자형 활용
      • 4.8.1. 실습: 계산기 만들기
    • 4.9. 문자열(Strings) 활용
      • 4.9.1. Unicode 한글의 사용
      • 4.9.2. 이스케이프 문자
      • 4.9.3. 문자열 연산자
      • 4.9.4. 문자열 포맷 연산자
      • 4.9.5. 내장 문자열 함수
    • 4.10. 시퀀스(Sequence) 자료형 활용
      • 4.10.1. 리스트(Lists)
      • 4.10.2. 튜플(Tuple)
      • 4.10.3. 딕셔너리(Dictionary)
    • 4.11 Class
    • 4.12. Date & Time
    • 4.13. 파이썬 에러처리
  • 5. 기초수학
  • 6. 머신러닝을 위한 파이썬
  • 7. 텐서플로 2.x
  • 8. 딥러닝을 이용한 자연어 처리 입문
  • 9. 파이토치로 시작하는 딥 러닝 입문
  • 9.6 6. Pytorch lightning
  • A1. 필수 학습 라이브러리들
    • 4.1 NumPy
      • 4.1.1. Basic Operations
      • 4.1.2. Indexing, Slicing 그리고 Iterating
      • 3.13.3. Shape Manipulation
    • 4.2 Matplotlib
    • 4.3 SciPy
      • 4.3.1. Interpolation
      • 4.3.2. Optimization
      • 4.3.3. Fast Fourier transforms: scipy.fftpack
    • 4.4 Pandas
      • 4.4.1 Pandas 자료구조
      • 4.4.2 Pandas 활용하기
  • A2. 머신러닝 & 딥러닝
    • 5.1. 머신러닝 개념 소개
      • 5.1.1. 경사하강법(Gradient Descent )
      • 5.1.2. 분류 (Classification)
      • 5.1.3. MNIST Dataset 소개
    • 5.2. 딥러닝 개념 소개
      • 5.2.1. 퍼셉트론
      • 5.2.2. 인공 신경망
      • 5.2.3. 대표적인 딥러닝 모델
    • 5.3. Tensorflow를 사용한 학습
      • 5.3.1. TensorFlow 기본 메커니즘
      • 5.3.2. Tensorflow Types
      • 5.3.3. 기본 동작 실습
      • 5.3.4. 선형 회귀
      • 5.3.5 로지스틱 회귀
    • 5.4. Keras를 사용한 학습
      • 5.4.1. Keras로 분석한 선형 회귀
      • 5.4.2. CNN(Convolutional Neural Network)
      • 5.4.3. Fashion MNIST with Keras
    • 5.5. 웹 크롤링
      • 5.5.1. requests와 BeautifulSoup으로 웹 크롤러 만들기
Powered by GitBook
On this page
  • 1.1. PyTorch Lightning 간단 예제
  • 1.2. 데이터 준비
  • 1.3. LightningModule Class
  • 1.4. MNIST 예제

Was this helpful?

9.6 6. Pytorch lightning

딥러닝 실험을 구현하기 위해서는 뉴럴네트워크와 같은 모델 코드 외에도 그 시스템을 만들고 실험을 수행하기 위한 많은 엔지니어링 코드가 필요합니다. 이러한 코드들은 직접 짜는게 귀찮을뿐더러 남이 짠 코드를 읽을 때도 코드를 분석하기 어렵게 만듭니다. 그런데 사실 딥러닝에서의 많은 엔지니어링 코드는 모델이 달라져도 그 역할이 비슷비슷한 경우가 많습니다.

머신러닝, 딜러닝 모델 구축을 할 때에 1)공통된 부분들을 반복해서 작성할 필요 없이 대신 처리해주고, 2)머신러닝 모델 구축의 탬플릿 코드로써 기능을 하며, 3)다른 사람이 작성한 코드를 쉽게 볼 수 있도록 공통된 스타일을 갖도록 하고 4)모델의 개별적인 부분은 유연하게 커스터마이징하여 실험할 수 있는 라이브러리가 PyTorch Lightning 입니다.

PyTorch Lightning은 PyTorch에 대한 High-level 인터페이스를 제공하는 오픈소스 Python 라이브러리입니다. PyTorch만으로도 충분히 다양한 AI 모델들을 쉽게 생성할 수 있지만 GPU나 TPU, 그리고 16-bit precision, 분산학습 등 더욱 복잡한 조건에서 실험하게 될 경우, 코드가 복잡해집니다. 따라서 코드의 추상화를 통해, 프레임워크를 넘어 하나의 코드 스타일로 자리 잡기 위해 탄생한 프로젝트가 바로 PyTorch Lightning입니다.

기존 PyTorch는 DataLoader, Mode, optimizer, Training roof 등을 전부 따로따로 코드로 구현을 해야하는데 Pytorch Lightning에서는 Lightning Model class 안에 이 모든것을 한 번에 구현하도록 되어있습니다. 클래스 내부에 있는 함수명은 똑같이 써야하고 그 목적에 맞게 코딩해야 합니다.

Pytorch Lightning은 크게 Trainer와 Lightning Module로 나누어 살펴볼 수 있습니다.

Lightning Module은 모델 내부의 구조를 설계하는 research & science 클래스라고 생각할 수 있습니다. 모델의 구조나 데이터 전처리, 손실함수 등의 설정을 통해 모델을 초기화 합니다. 실제로 코드에서는 pl.LightningModule 클래스를 상속받아 새로운 LightningModule 클래스를 생성합니다. 기존 PyTorch의 nn.Module과 같은 방식이라고 보시면 됩니다.

Trainer는 모델의 학습을 담당하는 클래스라고 볼 수 있습니다. 모델의 학습 epoch이나 batch 등의 상태뿐만 아니라, 모델을 저장해 로그를 생성하는 부분까지 담당합니다. 실제로 코드에서는 pl.Trainer()라고 정의하면 끝입니다.

결국 두 가지의 큰 클래스를 통해, 복잡한 양의 작업들을 2가지 영역으로 추상화할 수 있게 됩니다.

1.1. PyTorch Lightning 간단 예제

PyTorch Lightning을 사용하여 딥러닝 모델을 작성하는 순서는

1) Lightning Module에서 상속된 새로운 Lightning Module 클래스를 작성합니다.

2) DataLoader 를 통해 학습할 데이터를 준비 합니다.

3) Trainer 객체를 만들고, 그 Trainer에 데이터와 Lightning Module 클래스를 주어 학습합니다.

import pytorch_lightning as pl

class LitModel(pl.LightningModule):
    def __init__(self):
        super().__init__()
        self.l1 = nn.Linear(28 * 28, 10)

    def forward(self, x):
        return torch.relu(self.l1(x.view(x.size(0), -1)))

    def training_step(self, batch, batch_idx):
        x, y = batch
        y_hat = self(x)
        loss = F.cross_entropy(y_hat, y)
        return loss

    def configure_optimizers(self):
        return torch.optim.Adam(self.parameters(), lr=0.02)

train_loader = DataLoader(MNIST(os.getcwd(), download=True, transform=transforms.ToTensor()))
trainer = pl.Trainer()
model = LitModel()
trainer.fit(model, train_loader)

1.2. 데이터 준비

PyTorch의 데이터 준비하는 과정을 크게 5가지 형태로 구조화하여 처리합니다.

1) 다운로드

2) 데이터 정리 혹은 메모리 저장

3) 데이터셋 로드

4) 데이터 전처리 (특히, transforms를 의미)

5) dataloader 형태로 wrapping

위의 순서에 맞게 코드를 추상화합니다.

prepare_data()

train_dataloader, val_dataloader, test_dataloader

PyTorch 학습 과정에 관여하는 여러 코드가 추상화된 함수형태로 LightningModule안에 포함되어 있습니다. 특히, 상속받은 LightningModule 클래스는 위와 같은 함수들을 순서에 따라 실행하는데, 이를 바로 Lifecycle이라고 부릅니다. 즉, 해당하는 순서에 따라 함수를 작성하는 것이 중요합니다.

1.3. LightningModule Class

Lightning Module은 5가지로 구성됩니다.

Computations (init).

Train loop (training_step)

Validation loop (validation_step)

Test loop (test_step)

Optimizers (configure_optimizers)

Lightning Module에는 많은 편리한 Method가 있지만 핵심적으로 알아야 하는 Method 들은 다음과 같습니다.

Name

Description

init

Define computations here

forward

Use for inference only (separate from training_step)

training_step

the full training loop

validation_step

the full validation loop

test_step

the full test loop

configure_optimizers

define optimizers and LR schedulers

1.3.1. training_step method

일반적인 pyTorch training loop 를 training_step 메서드내에 배치 합니다.

class LitClassifier(pl.LightningModule):
    def __init__(self, model):
        super().__init__()
        self.model = model

    def training_step(self, batch, batch_idx):
        x, y = batch
        y_hat = self.model(x)
        loss = F.cross_entropy(y_hat, y)
        return loss

만약 epoch-level metric을 계산하고 log를 하려면 .log 메서드를 사용합니다.

def training_step(self, batch, batch_idx):
    x, y = batch
    y_hat = self.model(x)
    loss = F.cross_entropy(y_hat, y)

    # logs metrics for each training_step,
    # and the average across the epoch, to the progress bar and logger
    self.log("train_loss", loss, on_step=True, on_epoch=True, prog_bar=True, logger=True)
    return loss

만약에 각 training_step의 결과로 무엇인가 할 일이 있으면 training_epoch_end 메서드에 작성합니다.

def training_step(self, batch, batch_idx):
    x, y = batch
    y_hat = self.model(x)
    loss = F.cross_entropy(y_hat, y)
    preds = ...
    return {"loss": loss, "other_stuff": preds}


def training_epoch_end(self, training_step_outputs):
    for pred in training_step_outputs:
        ...

validation loop를 추가 하려면 validation_step 메서드를 추가 합니다.

class LitModel(pl.LightningModule):
    def validation_step(self, batch, batch_idx):
        x, y = batch
        y_hat = self.model(x)
        loss = F.cross_entropy(y_hat, y)
        self.log("val_loss", loss)

만약에 각 validation _step의 결과로 무엇인가 할 일이 있으면 validation _epoch_end 메서드에 작성합니다.

def validation_step(self, batch, batch_idx):
    x, y = batch
    y_hat = self.model(x)
    loss = F.cross_entropy(y_hat, y)
    pred = ...
    return pred


def validation_epoch_end(self, validation_step_outputs):
    for pred in validation_step_outputs:

1.4. MNIST 예제

이제 PyTorch Lightning 을 사용한 MNIST 학습 코드를 설명해 보겠습니다.

먼저 필요한 모듈 몇 가지를 설치해야 합니다.

!pip install --quiet torchmetrics torch “pytorch-lightning>=1.3" "torchvision"

작성되는 코드에서 사용할 라이브러리들을 import 합니다.

import os

import torch
import pytorch_lightning as pl
from pytorch_lightning import LightningModule, Trainer
from torch import nn
from torch.nn import functional as F
from torch.utils.data import DataLoader, random_split
from torchvision import transforms
from torchvision.datasets import MNIST

PATH_DATASETS = os.environ.get("PATH_DATASETS", ".")
AVAIL_GPUS = min(1, torch.cuda.device_count())
BATCH_SIZE = 256 if AVAIL_GPUS else 64

다음은 최소화된 MNIST 코드의 예제 입니다. training_step과 configure_optimizers 메서드는 필수적으로 구현해야 합니다.

class MNISTModel(LightningModule):
    def __init__(self):
        super().__init__()
        self.model = nn.Sequential(
            nn.Flatten(),
            nn.Linear(28 * 28, 64),
            nn.BatchNorm1d(64),
            nn.ReLU(inplace=True),
            nn.Linear(64, 64),
            nn.BatchNorm1d(64),
            nn.ReLU(inplace=True),
            nn.Linear(64, 10)
        )

    def forward(self, x):
        return self.model(x)

    def training_step(self, batch, batch_nb):
        x, y = batch
        logits = self.model(x)
        loss = F.cross_entropy(logits, y)
        return loss

    def validation_step(self, batch, batch_idx):
        x, y = batch
        logits = self.model(x)
        loss = F.cross_entropy(logits, y)
        self.log("train_loss", loss)
        return loss

    def test_step(self, batch, batch_idx):
        x, y = batch
        logits = self.model(x)
        loss = F.cross_entropy(logits, y)
        self.log("test_loss", loss)
        return loss

    def configure_optimizers(self):
        return torch.optim.Adam(self.parameters(), lr=0.02)

__init__ 에서 모델의 구조를 정의합니다. MNIST 를 위해 몇 개의 층을 Sequential로 쌓았습니다.

l forward는 모델의 추론 결과를 제공하고 싶을 때 사용합니다. nn.Module처럼 꼭 정의해야 하는 메서드는 아니지만 self(<입력>)과 같이 사용할 수 있게 만들어주므로 구현해주면 다른 메서드를 구현할 때 편리합니다.

l training_step은 학습 루프의 body 부분을 나타냅니다. 이 메소드에서는 argument로 training 데이터로더가 제공하는 batch와 해당 batch의 인덱스가 주어지고 학습 로스를 계산하여 리턴합니다. pytorch lightning은 편리하게도 batch의 텐서를 cpu 혹은 gpu 텐서로 변경하는 코드를 따로 추가하지 않아도 trainer의 설정에 따라 자동으로 적절한 타입으로 변경해줍니다.

l validation_step은 학습 중간에 모델의 성능을 체크하는 용도로 사용합니다. training_step과 마찬가지로 validation 데이터로더에서 제공하는 배치를 가지고 확인하고자 하는 통계량을 기록할 수 있습니다. 하나의 값을 저장할 때는 self.log(<변수 이름="">, <값>)과 같이 저장할 수 있고 여러 개의 변수를 저장하고 싶으면 아래 예시와 같이 self.log_dict로 변수 이름, 값 쌍을 가지고 있는 딕셔너리를 저장할 수 있습니다. 각 스탭마다 변수에 저장된 값의 평균이 해당 변수의 최종 값이 됩니다. 특별히 설정을 바꾸지 않으면 변수 중에 'val_loss'가 best 모델을 구하는 기준으로 사용됩니다. 예제에서는 모델의 정확도와 cross entropy loss를 구해서 저장합니다. 여기서 accuracy 함수는 pytorch_lightning.metrics.functional에서 정의되어 있는 함수로 logits에서 최댓값인 라벨이 실제 라벨과 일치하는 비율을 구해줍니다.

l configure_optimizers에서는 모델의 최적 파라미터를 찾을 때 사용할 optimizer와 scheduler를 구현합니다. GANs와 같이 여러 모델을 학습하기 위해 여러 optimizer를 사용해야 한다면 리스트로 리턴하면 됩니다. 이 경우에는 training_step에서 optimizer의 인덱스를 추가로 받아서 여러 모델을 번갈아 학습하게 됩니다. 예제에서는 학습해야 할 모델이 하나이므로 하나의 Adam optimzer만 사용하도록 하겠습니다.

pl.seed_everything(777)

# Init DataLoader from MNIST Dataset
dataset = MNIST(PATH_DATASETS, train=True, download=True, transform=transforms.ToTensor())

train_dataset, val_dataset = random_split(dataset, [55000, 5000])
test_dataset = MNIST('', train=False, download=True, transform=transforms.ToTensor())
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE)
val_loader = DataLoader(val_dataset, batch_size=BATCH_SIZE)
test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE)

# Initialize a trainer
trainer = Trainer(gpus=AVAIL_GPUS, max_epochs=3, progress_bar_refresh_rate=20,)

# Init our model
mnist_model = MNISTModel()

# Train the model ⚡
trainer.fit(mnist_model, train_loader)

trainer.test(test_dataloaders=test_loader)

학습 및 테스트에 사용할 MNIST 데이터셋을 불러옵니다. 여기서 학습 데이터셋의 일부를 랜덤으로 샘플링해 validation 용도로 사용하겠습니다. 각 나눈 데이터 셋을 가지고 training, validation, test용 데이터로더를 만듭니다.

모델을 학습하기 위해서는 학습 로직을 정하는 Trainer를 생성해야 합니다. Pytorch lightning의 Trainer는 굉장히 많은 기능을 제공합니다. 아래 예제에서는 간단히 학습 epoch 수와 gpu 수만 조정할 수 있도록 만들었습니다.

gpus가 0일 때는 cpu를 사용하고 gpus가 1 이상이면 gpu를 사용하여 모델을 학습합니다. gpus가 2 이상이면 자동으로 다중 gpu를 활용해 분산 학습을 진행하게 되는데 기본 설정은 process를 spawn하는 distributed data parallel 방식(ddp_spawn)으로 되어있습니다.

Trainer와 lightning module을 정의하고 난 뒤에 Trainer의 fit 함수로 모델을 학습할 수 있습니다. fit의 파라미터로 모델, training 데이터로더와 validation 데이터로더를 넘겨줍니다.

Pytorch lightning은 기본적으로 각 버전마다 체크포인트를 저장해줍니다. 하지만, 체크포인트 이름, 저장 주기, 모니터링할 metric 등을 바꾸고 싶으면 체크포인트 callback을 수정해주어야 합니다. 아래와 같이 ModelCheckpoint로 체크포인트 콜백을 생성합니다.

checkpoint_callback = ModelCheckpoint(

filepath=os.path.join('checkpoints', '{epoch:d}'),

verbose=True,

save_last=True,

save_top_k=args.save_top_k,

monitor='val_acc',

mode='max'

)

각 파라미터의 의미는 다음과 같습니다.

- filepath: 체크포인트 저장위치와 이름 형식을 지정합니다.

- verbose: 체크포인트 저장 결과를 출력합니다.

- save_last: 마지막 체크포인트를 저장합니다.

- save_top_k: 최대 몇 개의 체크포인트를 저장할지 지정합니다.(save_last에 의해 저장되는 체크포인트는 제외)

- monitor: 어떤 metric을 기준으로 체크포인트를 저장할지 지정합니다.

- mode: 지정한 metric의 어떤 기준(ex. min, max)으로 체크포인트를 저장할지 지정합니다.

Trainer 에 CheckPoint 를 적용하면 다음과 같이 코드를 수정해야 합니다.

from pytorch_lightning.callbacks import ModelCheckpoint

pl.seed_everything(777)

# Init DataLoader from MNIST Dataset
dataset = MNIST(PATH_DATASETS, train=True, download=True, transform=transforms.ToTensor())

train_dataset, val_dataset = random_split(dataset, [55000, 5000])
test_dataset = MNIST('', train=False, download=True, transform=transforms.ToTensor())
train_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE)
val_loader = DataLoader(val_dataset, batch_size=BATCH_SIZE)
test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE)

checkpoint_callback = ModelCheckpoint(
    filename='sample-mnist-epoch{epoch:02d}-val_loss{val/loss:.2f}',
    verbose=True,
    save_last=True,
    monitor='val_acc',
    mode='max'
)

# Initialize a trainer
trainer = Trainer(gpus=AVAIL_GPUS, max_epochs=3, progress_bar_refresh_rate=20,callbacks=[checkpoint_callback])

# Init our model
mnist_model = MNISTModel()

# Train the model ⚡
trainer.fit(mnist_model, train_loader)

Previous9. 파이토치로 시작하는 딥 러닝 입문NextA1. 필수 학습 라이브러리들

Last updated 3 years ago

Was this helpful?