반응형

1. 머신러닝 개요와 모델 기반 학습 

 

머신러닝은 데이터로부터 학습할 수 있도록 컴퓨터를 프로그래밍하는 것을 말합니다. 잘 설계된 머신러닝의 프로세스는 다음과 같이 정의할 수 있습니다. [1]

 

  • 목표 설정 (Business Goal)
  • 머신러닝 문제 정의 (ML Problem Framing)
  • 데이터 처리 (Data Processing) : 수집, 전처리, 피처 엔지니어링 등
  • 모델 개발 (Model Development) : 훈련, 평가, 튜닝
  • 모델 적용 (Deployment) 
  • 모델 모니터링 (Monitoring)

이중에서 모델 개발에 좀 더 집중해서 살펴보려고 합니다. 모델 개발을 위한 여러가지 접근 방식이 있지만, 그 중에서 아래와 같은 방식으로 진행하는 것을 '모델 기반 학습(model-based learning)'이라고 합니다. [2]

 

1) 모델 설정

2) 무작위로 파라미터 설정

3) 설정된 파라미터에 따라 예측값 계산

4) 예측값과 실제값의 차이 계산 - 손실함수

5) 손실 값이 작아지도록 파라미터 업데이트 - 최적화

6) 충분히 작아질 때까지 3~5 반복 

 

위 과정에서 손실함수와 최적화에 대해 조금 더 자세히 살펴보려고 합니다. 

2. torch.nn

PyTorch에서는 이러한 모델 기반 학습을 지원할 수 있도록 계산 그래프를 쌓을 수 있는 torch.nn을 제공합니다. 아래 사진에서 보이는만큼 머신러닝에 필요한 여러가지 기능을 가진 계산 그래프를 제공하고 있기 때문에 실제로 모든 것을 구현할 필요는 없습니다. 

 

torch.nn에서 제공하고 있는 다양한 블럭들 ('24.8.16 캡처)

 

특히, 손실함수는 torch.nn에 자체 클래스 또는 torch.nn.functional 함수로 제공하고 있고, 최적화는 torch.optim에 함수 형태로 이용 가능합니다.

3. 손실함수

손실함수는 머신러닝 모델이 얼마나 좋은지, 나쁜지를 정량화하는 함수로 모델을 통해 도출된 추정(예측)값과 기준(실제)값이 얼마나 다른지에 따라 모델에 페널티를 주는 정도를 다르게 합니다. 대표적인 손실함수는 MSE, Cross Entropy, 쿨백-라이블러 발산 등이 있습니다. 

3.1. MSE

평균제곱오차(Mean Squared Error, MSE)는 추정값과 기준값의 차이의 제곱의 평균입니다. 일반적인 수식은 쉽게 찾아볼 수 있으니, 익숙해져야 하는 행렬식으로 표현하면 아래와 같습니다. 여기서 e는 오차들로 이뤄진 벡터입니다. [3]

 

 

PyTorch에서 MSE를 계산하는 방법은 nn모듈에서 MSELoss 클래스를 사용하거나, nn.functional의 함수를 사용하면 됩니다.

 

nn.MSELoss()
nn.functional.mseloss()

 

 

3.2. Cross Entropy

크로스엔트로피(Cross Entropy)는 정보이론에서 두 확률분포를 구분하는데 필요한 평균비트 수를 측정하는 것을 말합니다. 특별한 경우로 0/1과 같이 이진 문제에 대해서는 Binary Cross Entropy(BCE)가 존재합니다. BCE에 대한 정의는 아래와 같습니다. [4]

 

 

PyTorch에서 Cross Entropy와 BCE를 계산하는 방법은 아래와 같습니다.

 

# Cross Entropy
nn.functional.cross_entropy()

# BCE
nn.BCELoss()
nn.functional.binary_cross_entropy()

 

4. 최적화

손실값이 가장 최소가 되는 순간은 미분적분 과목을 돌이켜볼 때 손실함수의 미분값, 즉 손실함수의 그래디언트가 0인 순간입니다. 최적화는 손실함수의 그래디언트가 0이 될 수 있도록 만드는 일련의 알고리즘으로 다양한 방식이 개발되어 왔습니다. 이 글에서는 경사하강법과 역전파를 우선 살펴보고자 합니다. 

 

파이토치에서는 torch.optim 패키지를 통해 최적화 알고리즘을 지원하고 있습니다. torch.optim에 각 알고리즘 클래스를 해 적용이 가능합니다. 최적화는 아래 코드와 같이 일련의 과정이 필요한데, 각 코드의 세부 의미는 '4.2. 역전파'의 과정입니다. [5]

 

# Simple verison
for input, target in dataset:
    optimizer.zero_grad() # 이전 단계에 계산된 그래디언트 초기화
    output = model(input) 
    loss = loss_fn(output, target)
    loss.backward() # 자동 미분 수행
    optimizer.step() # 그래디언트 값을 통해 업데이트
    
# Clousre
for input, target in dataset:
    def closure():
        optimizer.zero_grad()
        output = model(input)
        loss = loss_fn(output, target)
        loss.backward()
        return loss
    optimizer.step(closure)

 

4.1. 경사하강법

경사하강법(Gradient Descent)은 손실함수의 그래디언트(쉽게 말해 미분값)를 0이 되는 방향으로 계산하는 최적화 알고리즘입니다. 그림의 식은 경사하강법의 계산식이며,다음과 같은 방법으로 계산됩니다. 

 

경사하강법의 계산식 [6]

 

1) 임의의 값(첫번째)의 그래디언트 계산

2) 그래디언트에 계수(학습률, learning rate)를 곱한 것을 그 값에서 빼기

3) 뺀 값을 다음 값으로 1~2과정을 그래디언트가 0이 될 때까지 계산

 

하지만, 일반적으로 전체 훈련 세트를 대상으로 위의 알고리즘을 수행하는 것은 (데이터가 많다면) 매우 시간이 많이 걸릴 수 있습니다. 이를 해결하기 위해 제안된 확률적 경사하강법(Stochastic Gradient Descent, SGD)은 무작위로 샘플을 선택하고 그 샘플에 대해 그래디언트를 계산하는 것입니다. 파이토치 코드는 아래같이 구현됩니다. (세부 설명 링크)

 

torch.optim.SGD(params, lr, ...)

 

4.2. 역전파

오늘날의 신경망 모델들은 여러 연산(선형 방정식, 비선형 활성화 함수 등)들을 겹겹이 쌓은 계산 그래프를 네트워크 형태로 구축하고 있습니다. (다층 퍼셉트론이라고도 합니다.) 경사하강법은 하나의 손실함수에 대해서는 최적화가 가능하지만, 이렇게 쌓여있는 다층 퍼셉트론을 훈련하기에는 연산이 너무 많아질 수 있기 때문에 최적화 알고리즘으로는 적절하지 않습니다. 

 

이러한 문제를 해결하기 위해 제안된 역전파(Backpropagation)는 업그레이드된 경사하강법으로 출력값을 계산하는 정방향(forward), 오차 그래디언트를 계산하는 역방향(backward) 두가지 방향의 연산을 수행해 최적화합니다.   

 

1) 임의의 값에 대한 예측값을 계산 (정방향)

2) 계산 그래프의 역으로 그래디언트를 곱하고 값을 대입하여 각 단계의 그래디언트 계산

3) 2)를 반복하면서 최종 단계인 손실함수의 그래디언트까지 계산 (역방향)

4) 계산된 그래디언트 값으로 경사하강법을 수행해 값 업데이트 

 

(사실 이 과정을 글로 이해하는 것보다는 계산 그래프를 보면서 이해하는 것이 훨씬 나은데, 스탠포드 CS231n 강의자료가 제일 잘 이해되는 것 같아서 링크를 참고하시기 바랍니다.[7])

 

역전파는 각 노드별로 다양한 연산을 만들어야 하기 때문에 꽤 구조화된 프로그래밍이 필요합니다. 하지만, 파이토치에서는 아래와 같이 자동미분 연산을 지원하고 있습니다.

 

pred = model(data) # 정의된 model에 따른 예측값 (Forward pass 수행)
loss = (pred - label).sum() # 별도 정의한 손실함수 MSE, BCE 등 다른 것을 사용해도 됨
loss.backward() # Backward pass 수행
torch.optim.SGD(param, lr,...).step() # 경사하강법 수행. 결과값은 .grad에 저장

 

 

 

5. 참고자료

[1] https://docs.aws.amazon.com/wellarchitected/latest/machine-learning-lens/well-architected-machine-learning-lifecycle.html

[2] 오렐리앙 제롱, 『핸즈온 머신러닝 (2판)』

[3] https://en.wikipedia.org/wiki/Mean_squared_error

[4] https://en.wikipedia.org/wiki/Cross-entropy

[5] https://pytorch.org/docs/stable/optim.html

[6] https://ko.wikipedia.org/wiki/%EA%B2%BD%EC%82%AC_%ED%95%98%EA%B0%95%EB%B2%95

[7] https://cs231n.stanford.edu/slides/2018/cs231n_2018_ds02.pdf

 

 

반응형