반응형

목차

더보기

전체 모델 구축 프로세스(The full moel building process)

데이터 작업(Working with data)

모델 생성(Creating models)

모델 매개변수 최적화(Optimizing the Model Parameters)

모델 저장(Saving Models)

모델 불러오기(Loading Models)

요약(Summary)


전체 모델 구축 프로세스(The full moel building process)

여기에서는 기계 학습의 일반적인 작업을 위해 API를 통해 실행 예정

자세한 것은 각 세션의 링크 참조

 

데이터 작업(Working with data)

  • Pytorch:
    데이터 작업을 위한 두 가지 프리미티브(torch.utils.data.DataLoader, torch.utils.data.Dataset) 존재
  • torch.utils.data.DataLoader: Dataset을 iterable을 매핑
  • torch.utils.data.Dataset: 샘플 및 라벨 존재
%matplotlib inline
import torch
from torch import nn
from torch.utils.data import DataLoader
from torchvision import datasets
from torchvision.transforms import ToTensor, Lambda, Compose
import matplotlib.pyplot as plt

 

  • Pytorch:
    데이터셋을 포함하여 도메인별 라이브러리 제공: TorchText, TorchVision, TorchAudio
  • torchvision.datasets module:
    CIFAR, COCO 등의 실제 비전 데이터에 대한 Dataset 개체 포함되어 있음
  • 모든 TorchVision Dataset:
    샘플과 라벨을 수정하기 위한 trasform, target_transform 이라는 argument 존재
# Download training data from open datasets.
training_data = datasets.FashionMNIST(
    root="data",
    train=True,
    download=True,
    transform=ToTensor(),
)

# Download test data from open datasets.
test_data = datasets.FashionMNIST(
    root="data",
    train=False,
    download=True,
    transform=ToTensor(),
)


Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-images-idx3-ubyte.gz
Using downloaded and verified file: data/FashionMNIST/raw/train-images-idx3-ubyte.gz
Extracting data/FashionMNIST/raw/train-images-idx3-ubyte.gz to data/FashionMNIST/raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/train-labels-idx1-ubyte.gz
Using downloaded and verified file: data/FashionMNIST/raw/train-labels-idx1-ubyte.gz
Extracting data/FashionMNIST/raw/train-labels-idx1-ubyte.gz to data/FashionMNIST/raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-images-idx3-ubyte.gz
Using downloaded and verified file: data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz
Extracting data/FashionMNIST/raw/t10k-images-idx3-ubyte.gz to data/FashionMNIST/raw

Downloading http://fashion-mnist.s3-website.eu-central-1.amazonaws.com/t10k-labels-idx1-ubyte.gz
Using downloaded and verified file: data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz
Extracting data/FashionMNIST/raw/t10k-labels-idx1-ubyte.gz to data/FashionMNIST/raw

 

  • DataLoader에 Dataset을 인수(argument)로 전달, 아래와 같은 기능 지원
    dataset에 대한 iterable을 wrapping
    자동 배치, 샘플링, 셔플링, 멀티프로세스 데이터 로드
  • batch size = 64 -> dataloader iterable은 각 배치 당 64개의 피쳐 및 라벨 제공
batch_size = 64

# Create data loaders.
train_dataloader = DataLoader(training_data, batch_size=batch_size)
test_dataloader = DataLoader(test_data, batch_size=batch_size)

for X, y in test_dataloader:
    print("Shape of X [N, C, H, W]: ", X.shape)
    print("Shape of y: ", y.shape, y.dtype)
    break
    
# Display sample data
figure = plt.figure(figsize=(10, 8))
cols, rows = 5, 5
for i in range(1, cols * rows + 1):
    idx = torch.randint(len(test_data), size=(1,)).item()
    img, label = test_data[idx]
    figure.add_subplot(rows, cols, i)
    plt.title(label)
    plt.axis("off")
    plt.imshow(img.squeeze(), cmap="gray")
plt.show()

Shape of X [N, C, H, W]:  torch.Size([64, 1, 28, 28])
Shape of y:  torch.Size([64]) torch.int64

 

모델 생성(Creating models)

  • 신경망 정의 위해 nn.Module을 상속하는 클래스 생성
  • __init__: 네트워크 계층 정의
  • forward: 인풋이 네트워크를 통과하는 방법 정의
  • GPU 사용 가능한 경우 신경망 연산 가속
# Get cpu or gpu device for training.
device = "cuda" if torch.cuda.is_available() else "cpu"
print("Using {} device".format(device))

# Define model
class NeuralNetwork(nn.Module):
    def __init__(self):
        super(NeuralNetwork, self).__init__()
        self.flatten = nn.Flatten()
        self.linear_relu_stack = nn.Sequential(
            nn.Linear(28*28, 512),
            nn.ReLU(),
            nn.Linear(512, 512),
            nn.ReLU(),
            nn.Linear(512, 10),
            nn.ReLU()
        )

    def forward(self, x):
        x = self.flatten(x)
        logits = self.linear_relu_stack(x)
        return logits

model = NeuralNetwork().to(device)
print(model)


Using cuda device
NeuralNetwork(
  (flatten): Flatten(start_dim=1, end_dim=-1)
  (linear_relu_stack): Sequential(
    (0): Linear(in_features=784, out_features=512, bias=True)
    (1): ReLU()
    (2): Linear(in_features=512, out_features=512, bias=True)
    (3): ReLU()
    (4): Linear(in_features=512, out_features=10, bias=True)
    (5): ReLU()
  )
)

 

모델 매개변수 최적화(Optimizing the Model Parameters)

  • 모델 학습에 필요한 로스 함수 및 옵티마이저 정의
    loss function: nn.CrossEntropyLoss
    optimizer: Stochastic Gradient Descent
loss_fn = nn.CrossEntropyLoss()
learning_rate = 1e-3
optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)

 

  • 하나의 학습 루프 안에서의 모델의 동작:
  1. 배치로 제공된 학습 데이터 셋을 이용하여 예측 수행
  2. 오류 역전파
  3. 모델 학습
def train(dataloader, model, loss_fn, optimizer):
    size = len(dataloader.dataset)
    for batch, (X, y) in enumerate(dataloader):
        X, y = X.to(device), y.to(device)
        
        # Compute prediction error
        pred = model(X)
        loss = loss_fn(pred, y)
        
        # Backpropagation
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()

        if batch % 100 == 0:
            loss, current = loss.item(), batch * len(X)
            print(f"loss: {loss:>7f}  [{current:>5d}/{size:>5d}]")
  • 모델 잘 학습하고 있는지 확인:
    테스트 데이터셋 이용
def test(dataloader, model):
    size = len(dataloader.dataset)
    model.eval()
    test_loss, correct = 0, 0
    with torch.no_grad():
        for X, y in dataloader:
            X, y = X.to(device), y.to(device)
            pred = model(X)
            test_loss += loss_fn(pred, y).item()
            correct += (pred.argmax(1) == y).type(torch.float).sum().item()
    test_loss /= size
    correct /= size
    print(f"Test Error: \n Accuracy: {(100*correct):>0.1f}%, Avg loss: {test_loss:>8f} \n")
  • 학습 프로세스: 여러 에폭에 걸쳐 수행
  • 각 에폭 내에서 모델은 매개변수 학습
  • 모델의 정확도와 손실을 각 에폭에서 인쇄 -> 매 에폭마다 정확도가 증가하는지, 손실이 감소하는지 확인
epochs = 15
for t in range(epochs):
    print(f"Epoch {t+1}\n-------------------------------")
    train(train_dataloader, model, loss_fn, optimizer)
    test(test_dataloader, model)
print("Done!")


Epoch 1
-------------------------------
loss: 2.295773  [    0/60000]
loss: 2.297218  [ 6400/60000]
loss: 2.283425  [12800/60000]
loss: 2.278249  [19200/60000]
loss: 2.279926  [25600/60000]
loss: 2.260619  [32000/60000]
loss: 2.256614  [38400/60000]
loss: 2.248361  [44800/60000]
loss: 2.234987  [51200/60000]
loss: 2.211842  [57600/60000]
Test Error: 
 Accuracy: 41.4%, Avg loss: 0.034903 

Epoch 2
-------------------------------
loss: 2.227791  [    0/60000]
loss: 2.239108  [ 6400/60000]
loss: 2.196185  [12800/60000]
loss: 2.183881  [19200/60000]
loss: 2.218200  [25600/60000]
loss: 2.170907  [32000/60000]
loss: 2.167650  [38400/60000]
loss: 2.151818  [44800/60000]
loss: 2.121467  [51200/60000]
loss: 2.078620  [57600/60000]
Test Error: 
 Accuracy: 47.1%, Avg loss: 0.033028 

Epoch 3
-------------------------------
loss: 2.121974  [    0/60000]
loss: 2.144973  [ 6400/60000]
loss: 2.049951  [12800/60000]
loss: 2.025212  [19200/60000]
loss: 2.119183  [25600/60000]
loss: 2.028407  [32000/60000]
loss: 2.016531  [38400/60000]
loss: 1.999072  [44800/60000]
loss: 1.939542  [51200/60000]
loss: 1.869733  [57600/60000]
Test Error: 
 Accuracy: 47.2%, Avg loss: 0.030161 

Epoch 4
-------------------------------
loss: 1.966496  [    0/60000]
loss: 2.005283  [ 6400/60000]
loss: 1.842639  [12800/60000]
loss: 1.798291  [19200/60000]
loss: 1.996712  [25600/60000]
loss: 1.860519  [32000/60000]
loss: 1.833745  [38400/60000]
loss: 1.834117  [44800/60000]
loss: 1.752414  [51200/60000]
loss: 1.658906  [57600/60000]
Test Error: 
 Accuracy: 48.4%, Avg loss: 0.027377 

Epoch 5
-------------------------------
loss: 1.817958  [    0/60000]
loss: 1.873164  [ 6400/60000]
loss: 1.658233  [12800/60000]
loss: 1.604004  [19200/60000]
loss: 1.892859  [25600/60000]
loss: 1.728574  [32000/60000]
loss: 1.694584  [38400/60000]
loss: 1.716881  [44800/60000]
loss: 1.620669  [51200/60000]
loss: 1.520065  [57600/60000]
Test Error: 
 Accuracy: 51.3%, Avg loss: 0.025398 

Epoch 6
-------------------------------
loss: 1.705050  [    0/60000]
loss: 1.772956  [ 6400/60000]
loss: 1.524106  [12800/60000]
loss: 1.473383  [19200/60000]
loss: 1.793820  [25600/60000]
loss: 1.624757  [32000/60000]
loss: 1.595235  [38400/60000]
loss: 1.626289  [44800/60000]
loss: 1.523839  [51200/60000]
loss: 1.426233  [57600/60000]
Test Error: 
 Accuracy: 53.5%, Avg loss: 0.023906 

Epoch 7
-------------------------------
loss: 1.612589  [    0/60000]
loss: 1.694386  [ 6400/60000]
loss: 1.419676  [12800/60000]
loss: 1.378877  [19200/60000]
loss: 1.704812  [25600/60000]
loss: 1.536829  [32000/60000]
loss: 1.516409  [38400/60000]
loss: 1.551574  [44800/60000]
loss: 1.448999  [51200/60000]
loss: 1.354901  [57600/60000]
Test Error: 
 Accuracy: 54.4%, Avg loss: 0.022727 

Epoch 8
-------------------------------
loss: 1.532547  [    0/60000]
loss: 1.630929  [ 6400/60000]
loss: 1.336020  [12800/60000]
loss: 1.305433  [19200/60000]
loss: 1.631139  [25600/60000]
loss: 1.462314  [32000/60000]
loss: 1.452916  [38400/60000]
loss: 1.491249  [44800/60000]
loss: 1.388288  [51200/60000]
loss: 1.299752  [57600/60000]
Test Error: 
 Accuracy: 55.3%, Avg loss: 0.021782 

Epoch 9
-------------------------------
loss: 1.462481  [    0/60000]
loss: 1.578309  [ 6400/60000]
loss: 1.268808  [12800/60000]
loss: 1.243797  [19200/60000]
loss: 1.572057  [25600/60000]
loss: 1.400606  [32000/60000]
loss: 1.401813  [38400/60000]
loss: 1.444131  [44800/60000]
loss: 1.337315  [51200/60000]
loss: 1.257235  [57600/60000]
Test Error: 
 Accuracy: 55.8%, Avg loss: 0.021020 

Epoch 10
-------------------------------
loss: 1.402163  [    0/60000]
loss: 1.532682  [ 6400/60000]
loss: 1.213558  [12800/60000]
loss: 1.192357  [19200/60000]
loss: 1.524502  [25600/60000]
loss: 1.349040  [32000/60000]
loss: 1.359848  [38400/60000]
loss: 1.406721  [44800/60000]
loss: 1.294481  [51200/60000]
loss: 1.222457  [57600/60000]
Test Error: 
 Accuracy: 56.7%, Avg loss: 0.020403 

Epoch 11
-------------------------------
loss: 1.351255  [    0/60000]
loss: 1.496092  [ 6400/60000]
loss: 1.168390  [12800/60000]
loss: 1.149713  [19200/60000]
loss: 1.487448  [25600/60000]
loss: 1.306274  [32000/60000]
loss: 1.324405  [38400/60000]
loss: 1.376118  [44800/60000]
loss: 1.258274  [51200/60000]
loss: 1.193912  [57600/60000]
Test Error: 
 Accuracy: 57.4%, Avg loss: 0.019891 

Epoch 12
-------------------------------
loss: 1.305900  [    0/60000]
loss: 1.466068  [ 6400/60000]
loss: 1.130126  [12800/60000]
loss: 1.114587  [19200/60000]
loss: 1.458147  [25600/60000]
loss: 1.270395  [32000/60000]
loss: 1.293715  [38400/60000]
loss: 1.350162  [44800/60000]
loss: 1.227087  [51200/60000]
loss: 1.169333  [57600/60000]
Test Error: 
 Accuracy: 58.3%, Avg loss: 0.019452 

Epoch 13
-------------------------------
loss: 1.264979  [    0/60000]
loss: 1.439438  [ 6400/60000]
loss: 1.097137  [12800/60000]
loss: 1.085567  [19200/60000]
loss: 1.433970  [25600/60000]
loss: 1.239276  [32000/60000]
loss: 1.266291  [38400/60000]
loss: 1.327267  [44800/60000]
loss: 1.199434  [51200/60000]
loss: 1.148261  [57600/60000]
Test Error: 
 Accuracy: 59.0%, Avg loss: 0.019064 

Epoch 14
-------------------------------
loss: 1.227596  [    0/60000]
loss: 1.414626  [ 6400/60000]
loss: 1.067816  [12800/60000]
loss: 1.061232  [19200/60000]
loss: 1.413360  [25600/60000]
loss: 1.212436  [32000/60000]
loss: 1.240914  [38400/60000]
loss: 1.306429  [44800/60000]
loss: 1.174499  [51200/60000]
loss: 1.129985  [57600/60000]
Test Error: 
 Accuracy: 59.8%, Avg loss: 0.018713 

Epoch 15
-------------------------------
loss: 1.192792  [    0/60000]
loss: 1.391189  [ 6400/60000]
loss: 1.041390  [12800/60000]
loss: 1.040678  [19200/60000]
loss: 1.396070  [25600/60000]
loss: 1.188643  [32000/60000]
loss: 1.217234  [38400/60000]
loss: 1.287394  [44800/60000]
loss: 1.151905  [51200/60000]
loss: 1.113297  [57600/60000]
Test Error: 
 Accuracy: 60.6%, Avg loss: 0.018389 

Done!
  • 처음에 정확도 좋지 않을 수 있음
  • 에폭 수 늘리거나 learning_rate 증가 고려
  • 선택한 모델이 최적의 모델이 아닐 수 있음

 

모델 저장(Saving Models)

  • 모델을 저장하는 일반적인 방법:
    internal state dictionary를 직렬화(serialize)하는 것
torch.save(model.state_dict(), "data/model.pth")
print("Saved PyTorch Model State to model.pth")


Saved PyTorch Model State to model.pth

 

모델 불러오기(Loading Models)

  • 모델 로드하는 프로세스:
  1. 모델의 구조 생성
  2. 구조에 internal state dictionary 로드
model = NeuralNetwork()
model.load_state_dict(torch.load("data/model.pth"))


<All keys matched successfully>
  • 위 모델 사용하여 예측 가능
classes = [
    "T-shirt/top",
    "Trouser",
    "Pullover",
    "Dress",
    "Coat",
    "Sandal",
    "Shirt",
    "Sneaker",
    "Bag",
    "Ankle boot",
]

model.eval()
x, y = test_data[0][0], test_data[0][1]
with torch.no_grad():
    pred = model(x)
    predicted, actual = classes[pred[0].argmax(0)], classes[y]
    print(f'Predicted: "{predicted}", Actual: "{actual}"')


Predicted: "Sandal", Actual: "Ankle boot"

튜토리얼 완료

 


요약(Summary)

  • 현재까지 신경망 사용하여 기계 학습 모델 구축하는 핵심 개념 공부 및 pytorch로 구현
  • FashionMNIST 이용한 이미지 분류 모델 구축함
  • 다음과 같은 분야 배움
  • Tensor를 CPU, GPU와 함께 사용하는 방법
  • 데이터셋 manage, scale, normalize 방법
  • 신경망을 사용하여 모델을 구축하는 방법
  • 모델 최적화 방법
  • 모델 추론 최적화 방법(model.eval(), with torch.no_grad(), require_grad=False, tensor.detach() 등)
더보기
  • require_grad=False:
    텐서에 대한 그래디언트가 역방향 패스 중에 계산되어야 하는지 여부를 나타내는 PyTorch 텐서의 속성
    기본적으로 PyTorch에 의해 생성된 모든 텐서: requires_grad=True
    False인 경우 텐서에 대한 그래디언트는 역방향 전달 중에 계산되지 않으며 텐서의 grad 속성은 업데이트되지 않음
  • torch.no_grad():
    블록 내의 모든 텐서에 대한 그래디언트 추적을 일시적으로 비활성화하는 PyTorch에서 제공하는 컨텍스트 관리자
    그래디언트 추적이 비활성화되면 포워드 패스가 평소와 같이 수행되지만 그래디언트가 계산되지 않고 텐서의 그래드 속성이 업데이트되지 않음
    그래디언트가 필요하지 않을 때 계산 속도를 높이고 메모리를 절약하는 데 유용할 수 있음
  • detach():
    원래 텐서와 동일한 저장소를 공유하지만 그래디언트 추적이 비활성화된 새 텐서를 반환하는 PyTorch에서 제공하는 메서드
    원래 텐서는 수정되지 않지만 새 텐서는 기울기가 계산되지 않으며 grad 속성이 업데이트되지 않음
    사용자가 추가 계산을 위해 원래 텐서를 유지하고 싶지만 기울기가 흐르는 것을 방지하려는 경우에 유용할 수 있음

요약:
requires_grad=False: 텐서에 대한 그래디언트 추적을 영구적으로 비활성화하는 방법
torch.no_grad(): 그래디언트 추적을 일시적으로 비활성화하는 컨텍스트 관리자
detach(): 텐서를 계산 기록에서 분리하는 방법으로 유용할 수 있음, 그래디언트 흐르는 것 방지

반응형

+ Recent posts