Pytorch

Model

술임 2025. 4. 14. 20:32

Review of Neural Network Model

오차 산출 단계 Losses

정답을 알고 있는 입력 이미지 여러장을 딥러닝 모델에 넣었을 때 나온 예측 값과 정답을 비교

 

가중치 수정 단계 Optimization

틀린 정답에 대해서 optimize 함수로 가중치를 수정함

 

평가 단계 Evaluation

정답을 알고 있는 입력 이미지 여러장을 일부 학습된 딥러닝 모델에 넣었을 때 나온 예측 값과 정답을 비교

 

출력층

softmax layer를 통해서 확률분포화 시킨다.

 

Parametric vs Non-parametric

Parametric layers

* backpropagation을 통해 학습을 진행하는 계층

- loss를 통해 학습을 진행하는 계층

* 은닉층, 출력층, 합성곱 층

* 모델의 크기(메모리)를 좌우함

- 학습 파라미터가 커질수록 모델이 커짐

* 모델이 클수록 학습시간이 오래 걸리고, 더 많은 메모리를 필요로 하며 더 좋은 GPU성능을 요구함

-> CPU 안에서 하기 어려움

 

Non-parametric layers

* 학습을 진행하지 않고, 단순한 계산이나 정보 추출을 진행하는 계층

* 활성화 계층, 입력층, pooling 계층

* 모델의 크기에 변화가 없거나 오히려 줄여주는 역할 수행

- CNN의 풀링계층은 오히려 크기를 줄여줌

* 신호 전달을 주목적으로 함


나만의 모델 생성

모델 생성 Process

1) Layer 정의

* 모델에서 어떤 layer를 사용할 것인지 정의

- linear, ReLU같은게 layer

* 각 layer는 parameter를 추적함

- 현재는 각자 parameter가 있음.

* non-parametric layer는 사전에 정의하지 않는 경우도 존재

 

2) Forward 정의

모델을 어떤 구조, 어떤 layer를 할 것인지를 만들었으면 연결시켜주는 forward 함수를 정의해야함.

* 텐서의 흐름에 따라 실제 layer를 배치

* non-parametric layer는 여기서 호출하는 경우도 있음

* 모델을 call할 경우, forward 함수가 자동으로 호출됨

* forward 함수를 직접호출하지 않음

* 설계상 background operation이 존재함

class NeuralNetwork(nn.Module):		# class 명 : 내가 사용하고싶은 모델 명
									# nn.Module이라는 클래스를 상속받아야 함. 호출 필요
                                    #-> 파이토치에서 모든 레이어는 이 모듈로 구현되어 있음
  def __init__(self):
    super(NeuralNetwork, self).__init__()	# super를 통해 부모 클래스를 상속. __init__은 모두 사용된다는 뜻
    
	######################### 추가적으로 이제 사용하려고 하는 레이어들을 정의하면 됨 
    self.flatten=nn.Flatten()
    self.linear_relu_stack=nn.Sequential(	# Sequential : 순차적으로 레이어를 만듦
        nn.Linear(28*28, 512),
        nn.Relu(),
        nn.Linear(512,512),
        nn.Relu(),
        nn.Linear(512,10)
    )

  def forward(self, x): # input x가 들어왔을 때 
    x=self.flatten(x)   # 실제 레이어 x를 활성화 시킴
    logits=self.linear_relu_stack(x) # flattened x가 relu_stack에 들어감
    return logits

 

Model Layers : layer들의 집합

Layer

* pytorch에서 layer는 모듈 nn.Module로 구현

-> 인터페이스 같은 것. linear, pooling, flatten도 layer가 될 수 있음

* parametric, non-parametric 구분하지 않고 모두 모듈 클래스로 관리

* 하나의 모듈은 다양한 모듈을 포함할 수 있음

-> class 안에 또 모듈이 존재

-> sequential도 모듈 안에 모듈

 

모델 구성 방법

sequential()

블록 단위

* 텐서(or layer, or module)를 순차적으로 flow하는 컨테이너

* Layer를 직접 순차적으로 추가하거나, OrderedDict의 모듈을 통해 선언 가능

* Sequential의 forward() 메서드는 입력 텐서를 흘려보낸 후, 각 layer를 순차적으로 실행된 결과를 반환

- Sequential로 만들어진 것을 호출하면 순차적으로 규칙에 따라서 흘러가서 반환함.

e.g. Sequential()

=> Linear() -> ReLU() -> Linear() -> ReLU() =>

 

* Sequential은 전체 layer의 조합을 하나의 모듈(모델)로 고려

* Sequential vs. torch.nn.ModuleList :

Modulelist는 말 그대로 모듈의 list, -> 그냥 있기만 하고 연결되어있는 게 아님. 리스트로만 존재하는 상태

Sequential은 연결이 되어있음 -> 모듈이라서 forward라는 개념을 가지고 있어서 선언한 레이어들이 연결되어있음

 

model in model

* customize하게 만든 모델(모듈)을 순서와 상관없이 연계 가능

e.g. GAN

Generator와 Discriminator가 있음

Generator는 이미지를 만들어내고, Discriminator는 이미지가 무엇인지를 판별하는 역할임

두개가 같이 학습되면서 loss는 각각 있으면서도 상호적으로 작용함

* Sequential의 경우, 입력 값이 순차적으로 bypass

* 다양한 형태로 layer 조작 가능

 

모델 다루기

Get Parameters

모델의 학습 : 모델의 파라미터

parameters()

* parameter는 모듈과 함께 사용될 때 매우 특별한 속성을 가진 텐서 하위 클래스

* 모듈에 할당되면 parameter 목록에 자동으로 추가

params = model.parameters()

for p in parms:
	print(p.shape)

 

named_parameters()

* parameter 목록에 등록된 parameter를 이름 정보와 함께 호출

* 파라미터에 직접 접근해서 수정하게 되면 모델의 값이 변함

cf) 넘파이랑 텐서랑 서로 메모리로 관리하고 있어서 서로 값에 영향받음

named_params = model.named_parameters()

 

state_dict()

* 기본 기능은 named_parameter()과 동일

* 단, 자료형이 다르고 parameters(), named_parameters()함수와 다르게 tensor의 연결이 안되어있음

* state_dict 객체는 파이썬 dictionary 형이라서 쉽게 저장, 업데이트, 변경 및 복원 가능

* optimizer, 학습 가능한 parameter, 등록된 buffer가 있는 레이어에 state_dict 존재

* 특히 optimizer에는 옵티마이저의 상태와 사용된 하이퍼파라미터에 대한 정보 포함

* 파라미터 값을 변화해도 모델의 값은 변화하지 않음

-> 모델에 대해 저장하거나 변경하고 싶으면 state_dict을 호출해서 값을 받아서 거기서 수정하고, 완료된 결과를 모델에 load할 것. 

state_dict = model.state_dict()

for name, param in state_dict.items():
	print("{}: {}".format(name, param.shape))

state_dict()을 통해서 모델을 받고, 수정하고, 완료되면 기존 모델에 load시키면 수정된 내용이 반영됨

 

Save & Loading Model Weights

save the model

# 1. 현재 모델의 parameter 저장 (추후 확인용)
old_model = model.state_dict()

# 2. 모델 저장
torch.save(model.state_dict(), 'model.pth') # 경로

 

loading the model

model.load_state_dict(torch.load('model.pth'))
new_model = model.state_dict()

 

save the optimizer and buffers

from torch.optim import SGD

optimizer = SGD(model.parameters(), lr=0.01, momentum=0.9)
optim_state_dict = optimizer.state_dict()

 

Train & Evaluation Mode

def train(dataloader, model, loss_fn, optimizer):
  size=len(dataloader.dataset)
  model.train() 
  # overfitting 방지 1) dropout : 학습하는 단계에서 노드를 좀 끊어둠. 평가하는 단계에서는 노드 다 켜둠
  
  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}]")

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

'Pytorch' 카테고리의 다른 글

Loss and Optimizer  (0) 2025.05.01
Backpropagation & Activations  (0) 2025.04.22
Transform  (0) 2025.04.14
DataLoader  (0) 2025.04.11
Tensors Operation  (0) 2025.04.09