딥러닝은 기본 블럭인 뉴런(neuron)을 바탕으로 입력에 대하 선형 변환에 비선형 함수를 적용하는 역할을 수행합니다.
이를 통해 학습이 이뤄지는 것입니다.
이전 포스팅에서 해당 내용과 같이 모델이 어떻게 학습하는지 큰 그림을 그려봤으므로, 이번 포스팅에서는 파이토치 모듈을 활용하여 모델 아키텍처를 만들고 실제로 데이터가 어떻게 적합되는지, 학습되는지 알아보도록 하겠습니다.
1. 파이토치 nn모듈
파이토치에는 신경망 전용 서브모듈(module)이 있습니다.
이 모듈로 신경망 아키텍처를 만들 수 있는 빌딩 블럭이 있는데, 이를 모듈이라고 부릅니다.
파이토치의 모듈은 nn.Module 베이스 클래스에서 파생되었습니다.
하나이상의 parameter객체를 인자로 받는데 이는 텐서타입입니다.
-forward와 __call__메소드
파이토치가 제공하는 nn.Module의 모든 서브클래스에는 __call__메소드가 정의되어 있는데,
이를 통해 순전파 방향으로의 결과를 도출할 수 있습니다.
이해를 돕기 위해 이전 포스팅에서 온도계 변환에서 구현한 것과 같이 입력에 대한 아핀변환을
nn모듈을 사용하여 예시를 들어보겠습니다.
import torch.nn as nn
linear_model = nn.Linear(1,1)
linear_model(t_un_val)
nn.Module의 서브클래스인 nn.Linear를 인스턴스화하여 마치 함수처럼 사용했습니다.
(1,1)과 같이 인자를 가지고 모듈을 호출하면 동일한 인자로 forward를 수행합니다(순방향 연산).
여기서 사용된 선형모델(nn.Linear)은 세 개의 인자를 받습니다.
입력 피처의 수와 출력 피처의 수(입력 차원 수/ 출력 차원 수), 선형 모델이 편향값을 포함하는지의 여부(True(기본값) / False)
-배치 입력 만들기
nn.Module의 서브클래스는 한 번에 여러 개의 샘플을 다룰 수 있도록 설계되었습니다.
즉, 배치 입력을 만들 수 있다는 의미입니다.
따라서 한번에 여러 입력(batch)에 대한 출력을 만들 수 있게 되는 것입니다.
10개의 샘플에 대해 nn.Linear 서브클래스를 실행한다고 했을 때,
이 입력 텐서를 만들고 모델로 실행하는 코드로 간단하게 표현하면 다음과 같습니다.
x.torch.ones(10,1)
linear_model(x)
-배치 최적화
배치를 수행하는 이유는 다양하지만 주요 이유 중 하나는 연산량을 충분히 크게 만들어
준비한 자원을 최대한 활용하기 위해서입니다.
여러 입력을 묶어 하나를 배치로 한 번에 실행하면 노는 자원 없이 다른 유닛도 계산에 사용할 수 있도록 만드는 것입니다.
배치 최적화를 위해서는 B개의 입력을 B(배치 사이즈) x Nin(입력피처의 크기)으로 reshape 하면 됩니다.
온도계 데이터로 예를 들어보겠습니다.
t_c = [0.5, 14.0, 15.0, 28.0, ...., 21.0] #torch.size([11])
t_u = [35.7, 55.9, 58.2, 81.9, ...., 68.4]
t_c = torch.tensor(t_c).unsqueeze(1) #torch.size([11,1])
t_u = torch.tensor(t_u).unsqueeze(1)
최종적으로 훈련루프를 통해 입력을 받아 학습하는 코드 예시를 통해 확인할 수 있습니다.
def training_loop(n_epochs, optimizer, model, loss_fn,
t_u_train, t_u_val,t_c_train, t_c_val):
for epoch in range(1, n_epochs+1):
t_p_train = model(t_u_train)
loss_train = loss_fn(t_p_train, t_c_train)
t_p_val = model(t_u_val)
loss_val = loss_fn(t_p_val, t_c_val)
optimizer.zero_grad()
loss_train.backward()
optimizer.step()
linaer_model = nn.Linear(1,1)
optimizer = optim.SGD(linear_model.parameters(), lr = 1e-2)
training_loop(n_epochs = 3000, ..., loss_fn = nn.MSEloss(), ...)
2. 신경망 모델 만들기
선형 모델(이전 포스팅에서 다룬 내용) 대신 신경망을 근사 함수로 사용하도록 바꾸는 신경망 모델을 사용하면
결과가 더 좋아지지는 않을 것입니다. 온도계 보정 자체가 선형적이기 때문입니다.
하지만 신경망 모델을 직접 다루면서 이해한다면 나중에 파이토치를 통한 신경망 모델을 구축하는 데에 큰 도움이 될 것입니다.
따라서 앞에서 본 예시를 바탕으로 신경망 모델을 만들어 예시를 들어보겠습니다.
신경망 모델을 만든다는 것은 결국 다양한 입력 범위에 대해 활성 함수가 응답하고
이 출력을 선형적으로 결합한 후 출력 값을 만드는 것이라고 볼 수 있습니다.
결국, 모듈을 결합시키는 과정이 필요합니다.(다중 계층을 쌓아보자!)
이때, 필요한 것이 nn.Sequential 컨테이너입니다.
선형 모듈을 두 개 쌓아 모델을 구성하는 코드를 예로 들어보겠습니다.
seq_model = nn.Sequential(nn.Linear(1,13), nn.Tanh(), nn.Linear(13,1))
해당 모델의 첫 번째 모듈의 중간 출력은 이어지는 다른 모듈에 이어져 전달됩니다.
이것을 입력으로 받아 다른 모듈에 의해 출력이 발생하는 것입니다.
모델을 해석하면 하나의 차원을 가진 입력 피처로부터 13개의 피처를 은닉층으로 전달하고,
tanh함수를 통과한 값 13개를 하나의 출력피처로 만드는 선형 결합이다.라고 할 수 있겠습니다.
weights와 bias를 살펴보기 위해서는 model.parameters()를 호출하면 됩니다.
[params.shapea for param in seq_model.parameters()]
#out: [torch.Size([13,1]), torch.Size([13]), torch.Size([1,13]), torch.Size([1])]
지금까지 파이토치의 nn모듈을 사용하여 훈련을 진행하는 예시를 봤습니다.
이전 포스팅까지 미분 가능한 모델을 만들고 경사하강을 통해 자동 미분의 방식을 알게 되었으니,
결국 파이토치의 전반적인 신경망 다루는 방식에 대해 알아본 것입니다.
다음 포스팅에서부터는 실습 코드를 통해 신경망 학습을 살펴보도록 하겠습니다.
'Book Review > [파이토치 딥러닝 마스터] 리뷰' 카테고리의 다른 글
Data to Tensor: 이미지, 테이블, 시계열 , 텍스트 데이터를 텐서로 (0) | 2023.04.05 |
---|---|
모델 학습 기법 기초 (0) | 2023.04.05 |
파이토치: 텐서(Tensor) 구조체 (0) | 2023.03.24 |
딥러닝과 파이토치 (0) | 2023.03.21 |