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])