일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- parametric model
- 모수적 모델
- decorater
- monai
- genetic epidemiology
- tabular
- MRI
- parrec
- words encoding
- nfiti
- 확산텐서영상
- 확산강조영상
- Phase recognition
- parer review
- 코드오류
- paper review
- 파이썬
- TeCNO
- TabNet
- nibabel
- 유전역학
- non-parametric model
- MICCAI
- 비모수적 모델
- deep learning #segmentation #sementic #pytorch #UNETR #transformer #UNET #3D #3D medical image
- 데코레이터
- PYTHON
- Surgical video analysis
- nlp
- precision #정밀도 #민감도 #sensitivity #특이도 #specifisity #F1 score #dice score #confusion matrix #recall #PR-AUC #ROC-AUC #PR curve #ROC curve #NPV #PPV
- Today
- Total
KimbgAI
[pytorch] CrossEntropy Loss Function 본문
tensorflow를 주로 사용하다가 요즘 pytorch를 사용하려다보니 기본적인 것에서부터 정리가 필요하다고 느껴 남겨놓는다.
pytorch에서 제공해주는 CrossEntorpyLoss function에는 softmax가 기본적으로 결합되어있기 때문에 model의 logit에 softmax를 따로 설정해주지 않아도 된다.
즉, torch.nn.CrossEntropyLoss() 은 torch.nn.LogSoftmax() 과 torch.nn.NLLLoss() 의 결합이다.
코드로 살펴보자
# CrossEntropyLoss 사용 (Class=3)
import torch.nn as nn
import torch
from torch.nn import functional as F
criterion = nn.CrossEntropyLoss()
outputs = torch.tensor([[0.2439, 0.0890, 0.0890], [ 0.2258, 0.1119, 0.0890],
[-0.2149, 0.2282, 0.0890], [ 0.0222, -0.1259, 0.0890]])
labels = torch.tensor([[1, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]]).to(torch.float64)
print(outputs.shape, labels.shape)
loss = criterion(outputs, labels)
print(loss)
torch.Size([4, 3]) torch.Size([4, 3])
tensor(0.9862, dtype=torch.float64)
# LogSoftmax와 NLLLoss (Negative Log Lilkelihood Loss)를 결합하여 구성
import torch.nn as nn
import torch
from torch.nn import functional as F
criterion = nn.NLLLoss()
outputs = torch.tensor([[0.2439, 0.0890, 0.0890], [ 0.2258, 0.1119, 0.0890],
[-0.2149, 0.2282, 0.0890], [ 0.0222, -0.1259, 0.0890]])
labels = torch.tensor([0,0,1,2]).to(torch.long)
print(outputs.shape, labels.shape)
LogSoftmax = torch.nn.LogSoftmax(dim=1)
asd = LogSoftmax(outputs)
print(F.nll_loss(asd, labels))
torch.Size([4, 3]) torch.Size([4])
tensor(0.9862)
같은 값이 나오는 걸 알 수 있다.
* 하지만 받는 dtype이 약간 다르다는 점은 신기하다.
(같은 dtype을 사용하면 'expected scalar type Long but found Float' 과 같은 에러 발생)
** 또한 label shape과 형태도 다르게 넣어야한다는 점도 차이가 있다.
(tensorflow의 sparce_catrgorical_crossentropy 함수와 비슷하다)
아래는 이진분류는 위한 CrossEntropy Loss이다.
위와 비슷하게,
BCEWithLogitsLoss는 sigmoid를 포함한 Loss function이고,
BCELoss는 포함되어 있지 않다.
# BCEWithLogitsLoss
import torch.nn as nn
import torch
criterion = torch.nn.BCEWithLogitsLoss()
outputs = torch.tensor([[0.2439, 0.2258, 0.2282, 0.1259]])
labels = torch.tensor([[1, 1, 1, 0]]).to(torch.float32)
print(outputs.shape, labels.shape)
loss = criterion(outputs, labels)
print(loss)
torch.Size([1, 4]) torch.Size([1, 4])
tensor(0.6272)
# BCELoss (sigmoid function 추가함)
import torch.nn as nn
import torch
criterion = nn.BCELoss()
outputs = torch.tensor([[0.2439, 0.2258, 0.2282, 0.1259]])
labels = torch.tensor([[1, 1, 1, 0]]).to(torch.float32)
print(outputs.shape, labels.shape)
loss = criterion(torch.sigmoid(outputs), labels)
print(loss)
torch.Size([1, 4]) torch.Size([1, 4])
tensor(0.6272)
끝!