PyTorch: Classification에서의 Output Func(~Activation Func.)와 Loss Func. 요약
PyTorch는 다양한 종류의 손실 함수와 활성화 함수를 제공하는데,
이 중에서 classification task를 수행하는 모델에서 사용되는 것들을 위주로 정리함.
최종 출력 함수로 사용되는 activation functions 와 이들과 같이 사용되는 loss functions는 다음과 같음.
- 최종 출력으로로사용되는 activation functions:
Sigmoid
,Softmax
,LogSoftmax
- loss functions:
BCELoss
,BCEWithLogitsLoss
,CrossEntropyLoss
,NLLLoss
활성화 함수(Activation Functions)
1. Sigmoid
Sigmoid
는 logit score 입력을 0과 1 사이의 probability 값으로 변환하는 activation function임.
- 엄격하게 애기하면 Logistic Function임.
주로 binary classification을 위한 model의 출력을 위해 사용됨.
import torch
# import torch.nn.functional as F
# 원시 출력값 (logits)
logits = torch.tensor([2.0, -1.0, 0.5])
# Sigmoid 적용
sigmoid_outputs = torch.sigmoid(logits)
# Print Output
torch.set_printoptions(precision=2)
print('Sigmoid outputs:', sigmoid_outputs)
https://dsaint31.tistory.com/320
https://dsaint31.tistory.com/430
2. Softmax
Softmax
는 각 class에 해당하는 logit score로 구성된 vector를 입력으로 하여, 이들 각각에 속할 probability 값들을 요소로 가지는 vector (~probability distirbution)를 출력함.
- 결과 vector의 모든 요소의 값을 더하면 1.0 이 되며, mutually exclusive 로 class 가 결정되는 경우의 최종 출력 vector를 구하는 데 사용됨.
- 이를 수학적으로 표현(?)하면 입력 벡터를 확률 분포로 변환한다고 할 수 있음.
Multi-class Classification을 위한 모델의 출력층으로 사용됨.
다음 functional api로 softmax를 사용하는 예를 보여줌.
import torch
import torch.nn.functional as F
# 원시 출력값 (logits)
logits = torch.tensor([2.0, 1.0, 0.1])
# Softmax 적용
softmax_outputs = F.softmax(logits, dim=-1)
print(f'{softmax_outputs=}')
- torch.nn.functional은 PyTorch에서 다양한 신경망 연산 및 함수들을 제공하는 module.
- 이 module은 신경망의 여러 layers, activation functionis, loss functions 등을 Functional API로 제공.
- Class의 인스턴스로 만드는 경우보다 보다 쉽고 독립적으로 사용가능하다는 장점을 가져서, 주로 학습되는 weight이 없는 함수들의 사용에 많이 사용되는 방식임.
다음은 class를 이용하여 softmax를 사용하는 방식임.
import torch
# Softmax 모듈 초기화 (dim=-1은 텐서의 마지막 차원을 기준으로 softmax를 적용)
softmax = torch.nn.Softmax(dim=-1)
# 원시 출력값 (logits)
logits = torch.tensor([2.0, 1.0, 0.1])
# Softmax 적용.
softmax_outputs = softmax(logits)
print(f'{softmax_outputs=}')
https://dsaint31.tistory.com/294
3. LogSoftmax
LogSoftmax
는 Softmax
의 출력에 (자연)로그를 적용한 함수임.
- softmax로 얻어진 확률분포에 해당하는 vector를 일종의 likelihood로 생각하고,
- 모델이 정답인 class의 likelihood를 극대화하도록 최적화할 때 사용되는 loss 함수인
- negative log likelihood (NLL) loss 와 함께 사용되게 하기 위해 아예 softmax결과에 log를 취한 결과가 나오도록 한 함수임.
softmax에 log를 취하는 형태의 구현은 0에 가까운 값을 가질 때, 수치해석적 구현에 문제가 발생하기 쉽기 때문에
이를 고려하여 stable하게 동작하도록 구현한 LogSofmax를 PyTorch가 제공해줌.
이같은 이유로 거의 대부분의 경우, 손실함수 NLLLoss
와 함께 사용된다.
# LogSoftmax 적용
log_softmax_outputs = F.log_softmax(logits, dim=0)
print('LogSoftmax outputs:', log_softmax_outputs)
https://dsaint31.tistory.com/578
https://pytorch.org/docs/stable/generated/torch.nn.LogSoftmax.html#logsoftmax
손실 함수(Loss Functions)
pred(=prediction)와 label의 값들을 비교하여 그 차이에 해당하는 값을 반환하여
model의 성능을 하나의 scalar값으로 나타냄.
loss function이 클수록 모델의 예측치인 pred 는 원래 나와야하는 label과 차이 크며,
이는 모델의 parameters가 아직 최적의 값과 거리가 큼을 의미함.
1. BCELoss (Binary Cross Entropy Loss)
BCELoss
는 binary classification에 사용되는 loss func.임.
이 loss는 model의 출력과 타겟 라벨이 모두 0과 1 사이의 값이어야 하기 때문에,
이 loss를 사용하는 모델의 출력은 Sigmoid
임.
- pred: Sigmoid (엄밀한 의미로는 logistic function)를 통과한 probability 값.
- label: 0과 1 사이의 실제 라벨 값 (0과 1만 선택한다해도, float tensor여야 함.)
import torch.nn as nn
# 예측값과 실제값
outputs = torch.tensor([0.7, 0.2, 0.9], requires_grad=True).float()
targets = torch.tensor([1.0, 0.0, 1.0]).float()
# BCELoss 선언
criterion = nn.BCELoss()
# 시그모이드 활성화 적용
outputs = torch.sigmoid(outputs)
# 손실 계산
loss = criterion(outputs, targets)
print('BCELoss:', loss.item())
https://pytorch.org/docs/stable/generated/torch.nn.BCELoss.html#bceloss
https://dsaint31.tistory.com/290
2. BCEWithLogitsLoss
BCEWithLogitsLoss
는 BCELoss
의 variation임: Binary Classification임.
내부적으로 sigmoid 함수를 결합시켜놓았기 때문에, 입력으로 logit score를 받을 수 있음.
(Sigmoid
적용 후 BCELoss
를 적용하던 것을 하나로 만든 형태임.)
이BCEWithLogitsLoss
가
수치해석적 구현의 관점에서는 보다 stable하고 effective함.
- pred: Sigmoid Activation Function의 입력값인 logit score.
- label: 0과 1 사이의 실제 라벨 값
import torch
import torch.nn as nn
# 원시 출력값 (시그모이드 활성화 적용 전 raw score)
raw_outputs = torch.tensor([0.5, -1.0, 2.0], requires_grad=True)
targets = torch.tensor([1.0, 0.0, 1.0])
# BCEWithLogitsLoss 선언
criterion = nn.BCEWithLogitsLoss()
# 손실 계산 (시그모이드 내부 적용)
loss = criterion(raw_outputs, targets)
print(f'BCEWithLogitsLoss: {loss.item():.4f}')
https://pytorch.org/docs/stable/generated/torch.nn.BCEWithLogitsLoss.html#bcewithlogitsloss
3. CrossEntropyLoss
CrossEntropyLoss
는 multi-class classification에 사용됨.
주의할 것은 PyTorch의CrossEntropyLoss
는 내부적으로Softmax
함수를 적용하고 있어서,
logit score vector를 입력으로 한다는 점임.
이 함수가 최적으로 동작하는 경우는 입력이 logit score vector이며, Label(or Target)은 클래스의 인덱스 형태로 제공되는 경우임.
(Label을 확률 vector로 제공가능하지만 이 경우 구동의 효율이 떨어짐.)
- 입력: softmax activation 안 거친 ANN의 raw score.
- 출력: 클래스 인덱스 (예: 0, 1, 2, ...) : long (=int64)를 dtype로 가짐.
import torch
import torch.nn as nn
# 원시 출력값 (softmax 활성화 적용 전)
raw_outputs = torch.tensor(
[[1.0, 2.0, 3.0],
[1.0, 2.0, 0.0],
[0.0, 2.0, 1.0]],
requires_grad=True).float()
targets = torch.tensor([2, 0, 1]).long() # 각 샘플의 클래스 인덱스
print(targets.dtype)
# CrossEntropyLoss 선언
criterion = nn.CrossEntropyLoss()
# 손실 계산 (softmax 내부 적용)
loss = criterion(raw_outputs, targets)
print(f'CrossEntropyLoss: {loss.item():.2f}')
https://pytorch.org/docs/stable/generated/torch.nn.CrossEntropyLoss.html#crossentropyloss
4. NLLLoss (Negative Log Likelihood Loss)
NLLLoss
는 로그 확률을 입력으로 사용하며, 주로 LogSoftmax
와 함께 사용됨.
- 실제로는 negation과 mean (또는 sum)만의 처리만 이루어짐.
- softmax와 log는 앞서 존재하는
LogSoftmax
에서 이루어짐.
이 조합을 통해 CrossEntropyLoss
와 유사한 효과를 낼 수 있지만 더 세밀한 컨트롤이 가능함.
- 입력: 로그 확률 (LogSoftmax의 출력)
- 출력: 클래스 인덱스 (예: 0, 1, 2, ...)
import torch
import torch.nn
# 모델 출력
logits = torch.tensor(
[[0.1, 0.2, 0.7], # max idx 2
[0.8, 0.1, 0.1], # max idx 0
[0.3, 0.5, 0.2]], # max idx 1
requires_grad=True).float()
# 타겟 클래스 인덱스
targets = torch.tensor([2, 0, 1]).long()
# 로그 소프트맥스 적용
log_softmax = F.log_softmax(logits, dim=1)
# NLLLoss 선언
criterion = nn.NLLLoss()
loss = criterion(log_softmax, targets)
print(f'NLLLoss with LogSoftmax: {loss.item():.2f}')
https://pytorch.org/docs/stable/generated/torch.nn.NLLLoss.html
https://dsaint31.me/mkdocs_site/ML/ch03/logistic_regression/#negative-log-likelihood
5.MultiLabelSoftMarginLoss
multi-label classification을 위한 loss function.
2024.05.30 - [분류 전체보기] - [DL] MultiLabelSoftMarginLoss: Multi-label classification
결론
앞서 소개한 loss function과 activation function은 PyTorch를 사용하는 딥러닝 모델을 구축하고 효과적으로 훈련하는 데 필수적임.
각 함수의 선택과 사용은 model의 특성과 task의 유형에 따라 달라질 수 있음.
- Binary Classification:
BCELoss
(+sigmoid) 또는BCEWithLogitsLoss
(+logit) 를 사용.
- Multi-label Classification:
sigmoid
(vector) +BCELoss
- logit score vector +
MultiLabelSoftMarginLoss
- Multiple-class Classification:
CrossEntropyLoss
(+logit) 를 사용하거나LogSoftmax
와NLLLoss
의 조합을 사용할 수 있음.
- Activation Function:
Sigmoid
는 binary classification(이진 분류)에서,Softmax
는 mutiple-class classification(다중 클래스)의 확률을 직접 계산하고,- loss 와 같이 연계되지 않는 점 기억.
LogSoftmax
는 확률의 로그 값을 계산하여 보다 수치적으로 stable(안정적)인 결과를 제공.
같이 보면 좋은 자료들
https://gist.github.com/dsaint31x/e631a1584f04703d428e3c034e6c63b1
'Python' 카테고리의 다른 글
[ML] Classification 과 관련 metrics 에 대한 소개. (0) | 2024.06.01 |
---|---|
[DL] Dataset: CIFAR-10 (0) | 2024.05.30 |
[ML] Dataset: Wisconsin Breast Cancer Dataset (0) | 2024.05.18 |
[DL] Dataset: Boston Housing Price (1) | 2024.04.18 |
[Python] collections.abc (0) | 2024.04.15 |