loss function Negative log likelihood loss nn.NLLLoss – Fungsi Negatif Log-Likelihood Loss (NLL) untuk target multiclass dengan menerapkan fungsi softmax sebagai lapisan aktivasi keluaran. Softmax mengacu pada fungsi aktivasi yang menghitung fungsi eksponensial yang dinormalisasi dari setiap unit di lapisan.
Fungsi Softmax dinyatakan sebagai:
![]()
NLL menggunakan konotasi negatif karena probabilitas (atau kemungkinan) bervariasi antara nol dan satu, dan nilai logaritma dalam rentang ini negatif. Pada akhirnya, nilai kerugian menjadi positif.
Di NLL, meminimalkan fungsi kerugian membantu kita mendapatkan output yang lebih baik. Kemungkinan log negatif diperoleh dari perkiraan perkiraan kemungkinan maksimum (MLE). Ini berarti bahwa kita mencoba untuk memaksimalkan kemungkinan log model, dan sebagai hasilnya, meminimalkan NLL.
Dalam NLL, model akan diberikan penalti / hukuman karena membuat prediksi yang benar dengan probabilitas yang lebih kecil dan didorong untuk membuat prediksi dengan probabilitas yang lebih tinggi. NLL tidak hanya peduli tentang prediksi yang benar tetapi juga tentang model yang yakin tentang prediksi dengan skor tinggi.
Misalkan kita punyai 3 record dengan 5 ciri fitur/paramater yaitu
m = nn.LogSoftmax(dim=1)
nll_loss = nn.NLLLoss()
# size of input (N x C) is = 3 x 5
input = torch.randn(5, 4, requires_grad=True)
# every element in target should have 0 <= value < C
target = torch.tensor([0,1,2,3,3])
output = nll_loss(m(input), target)
output.backward()
print(‘input: ‘, input)
print(‘target: ‘, target)
print(‘output: ‘, output)
arti dari
- m = nn.LogSoftmax(dim=1) artinya akan di kalkulasi berdasarkan perbaris yaitu dim=1 kalau diubah perkolom menjadi dim=0. Pytorch menganut jumlah sample sebagai baris/record dengan jumlah ciri fitur sebagai kolom. Misalkan kita mempunyai 100 record dengan 3 ciri fitur maka torch.randn(100, 3, requires_grad=True)
- # size of input (N x C) is = 3 x 5 yaitu kita mempunyai 3 record dengan 5 fitur
- # every element in target should have 0 <= value < C artinya kita harus mempunyai target dengan rentang tersebut
Kapan itu bisa digunakan?
Masalah klasifikasi multi-kelas, jadi misalkan ada 4 kelas kalian bisa menggunakan target nilai 0,1,2,3
Contoh kasus
Lebih jelasnya Cara menggunakan loss function Negative log likelihood loss nn.NLLLoss yaitu untuk klasifikasi multiclass seperti dataset MNIST yang terdiri dari 10 kelas sehingga target isinya [0,1,2,3,4,5,6,7,8,9]. Mengingat target berupa angka tersebut maka kalian wajib menggunakan fungsi aktifasi ReLU. Langsung saja kita buat model arsitekturnya (sederhana saja hanya MLP bukan CNN sehingga tidak perlu ada Conv2D)
import os
import torch
from torch import nn
from torchvision.datasets import MNIST
from torch.utils.data import DataLoader
from torchvision import transforms
class MLP(nn.Module):
'''
Multilayer Perceptron.
'''
def __init__(self):
super().__init__()
self.layers = nn.Sequential(
nn.Flatten(),
nn.Linear(28 * 28 * 1, 64),
nn.ReLU(),
nn.Linear(64, 32),
nn.ReLU(),
nn.Linear(32, 10),
nn.LogSoftmax(dim = 1)
)
def forward(self, x):
'''Forward pass'''
return self.layers(x)
Perhatikan kode nn.Linear(32, 10) yang mengindikasikan keluaranya terdiri dari 10 kolom, kemudian langsung di nn.LogSoftmax(dim = 1) . Berikut kode pelatihannya
if __name__ == '__main__':
# Set fixed random number seed
torch.manual_seed(42)
if os.path.exists('data')==False:
os.mkdir('data')
# Prepare MNIST dataset
dataset = MNIST('data', download=True, transform=transforms.ToTensor())
trainloader = torch.utils.data.DataLoader(dataset, batch_size=10, shuffle=True, num_workers=1)
# Initialize the MLP
mlp = MLP()
# Define the loss function and optimizer
loss_function = nn.NLLLoss()
optimizer = torch.optim.Adam(mlp.parameters(), lr=1e-4)
# Run the training loop
for epoch in range(0, 5): # 5 epochs at maximum
# Print epoch
print(f'Starting epoch {epoch+1}')
# Set current loss value
current_loss = 0.0
# Iterate over the DataLoader for training data
for i, data in enumerate(trainloader, 0):
# Get inputs
inputs, targets = data
# Zero the gradients
optimizer.zero_grad()
# Perform forward pass
outputs = mlp(inputs)
# Compute loss
loss = loss_function(outputs, targets)
# Perform backward pass
loss.backward()
# Perform optimization
optimizer.step()
# Print statistics
current_loss += loss.item()
if i % 500 == 499:
print('Loss after mini-batch %5d: %.3f' %
(i + 1, current_loss / 500))
current_loss = 0.0
# Process is complete.
print('Training process has finished.')
Setelah selesai training sebanyak 5 epoch, kita akan uji menggunakan kode berikut, perhatikan kode prediksi = torch.argmax(prediksi,dim=1) untuk menentukan index/lokasi value terbesar
a,b = next(iter(trainloader))
prediksi = mlp(a)
prediksi = torch.argmax(prediksi,dim=1)
print('target ',b)
print('prediksi ',prediksi)
hasilnya
print('target ',b)
target tensor([9, 5, 5, 2, 8, 9, 9, 6, 8, 4])
print('prediksi ',prediksi)
prediksi tensor([9, 5, 5, 8, 8, 9, 9, 6, 2, 4])