KimbgAI

[pytorch] CrossEntropy Loss Function 본문

machine learning

[pytorch] CrossEntropy Loss Function

KimbgAI 2022. 10. 4. 15:48
반응형

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)

 

 끝!

반응형
Comments