×

RNN untuk Image Recognition

RNN untuk Image Recognition

622 Views

RNN mempunyai keunggulan yang tidak dimiliki oleh model CNN yaitu kemampuan untuk menangani data yang bersifat time serial/berbasis waktu yang artinya data yang diolah akan dipengaruhi dari sequence sebelumnya.

Sehingga RNN sangat cocok sekali digunakan pada Natural Language Processing, seperti dibahas pada dasar-dasar RNN sebelumnya, saya akan memberikan contoh sederhana untuk kasus yang lain seperti tugas recognition sehingga RNN yang digunakan dengan jenis one to one

Model RNN ini sangat sederhana, bahkan kalian bisa pelajari lebih lengkap di referensi yang saya cantumkan dibawah ini. Studi kasus recognition yang sudah menjadi kebiasaan secara umum yaitu untuk mengenali character pada dataset MNIST.

Dataset MNIST

Merupakan dataset yang terdiri dari tulisan tangan 0 sampai 9 dengan ribuan data. Kalian cukup download saja dengan format yang ringkas yaitu ubyte https://softscients.com/2021/06/01/format-ubyte-dan-tfrecorddataset/ . Tapi nggak usah galau, bagaimana dataset nanti dibaca. Agar lebih mudah, kita langsung import semua kebutuhan package nya

from tqdm import tqdm
import torch.nn as nn
import torch
import torchvision
import torchvision.transforms as transforms
from torch.utils.data import Dataset
from PIL import Image
import glob
from torch.utils.data.dataloader import DataLoader
import numpy as np
from matplotlib import pyplot as plt
import torch.optim as optim

# Device
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

Kemudian kita langsung saja download yang akan dimasukan kedalam folder bernama data, sehingga kita setting True agar bisa perintah proses download.

BATCH_SIZE = 64
# list all transformations
transform = transforms.Compose([transforms.ToTensor()])

# download and load training dataset
trainset = torchvision.datasets.MNIST(root='./data', train=True,download=True, transform=transform)
trainloader = torch.utils.data.DataLoader(trainset, batch_size=BATCH_SIZE,shuffle=True, num_workers=2)

# download and load testing dataset
testset = torchvision.datasets.MNIST(root='./data', train=False,download=True, transform=transform)
testloader = torch.utils.data.DataLoader(testset, batch_size=BATCH_SIZE,shuffle=False, num_workers=2)

Oiya untuk dataset nya nanti kita bisa tersendiri Pytorch General Dataset bila ingin menggunakan data selain MNIST. Oiya untuk ukuran dataset berupa gambar dengan ukuran 28 x 28 ya, mari kita bisa telisik lebih jauh dengan memanggil dataset tersebut

dataiter = next(iter(trainloader))
images, labels = dataiter
print(images.shape,labels)

hasilnya kalian bisa melihat 1 batch dengan jumlah 64 file gambar dengan format grayscale alias 1 layer serta ukuran 28 x 28. Target berisi angka 0 sampai 9

torch.Size([64, 1, 28, 28]) 
tensor([9, 9, 2, 9, 9, 9, 4, 8, 4, 8, 4, 9, 3, 1, 0, 8, 4, 3, 1, 2, 6, 7, 6, 1,
        2, 8, 0, 1, 9, 1, 2, 3, 7, 9, 0, 8, 2, 0, 6, 3, 5, 1, 3, 4, 1, 1, 8, 8,
        4, 4, 2, 6, 9, 4, 4, 6, 6, 1, 5, 7, 0, 6, 3, 4])

 

See also  Membuat Demo Deep Learning dengan web based application

Model RNN

Penerapan RNN ada banyak versi, kita menggunakan versi yang sederhana dulu dan memang terbukti bisa digunakan pada kasus dataset MNIST serta jangan kaget bila model RNN dibawah ini belum tentu cocok untuk dataset yang lainnya karena based on karakteristik dataset yang kalian gunakan.

class ImageRNN(nn.Module):
    def __init__(self, batch_size, n_steps, n_inputs, n_neurons, n_outputs):
        super(ImageRNN, self).__init__()
        self.n_neurons = n_neurons
        self.batch_size = batch_size
        self.n_steps = n_steps
        self.n_inputs = n_inputs
        self.n_outputs = n_outputs
        
        self.basic_rnn = nn.RNN(self.n_inputs, self.n_neurons) 
        
        self.FC = nn.Linear(self.n_neurons, self.n_outputs)
        
    def init_hidden(self,):
        # (num_layers, batch_size, n_neurons)
        return (torch.zeros(1, self.batch_size, self.n_neurons))
        
    def forward(self, X):
        # transforms X to dimensions: n_steps X batch_size X n_inputs
        X = X.permute(1, 0, 2) 
        
        self.batch_size = X.size(1)
        self.hidden = self.init_hidden()
        
        # lstm_out => n_steps, batch_size, n_neurons (hidden states for each time step)
        # self.hidden => 1, batch_size, n_neurons (final state from each lstm_out)
        lstm_out, self.hidden = self.basic_rnn(X, self.hidden)      
        out = self.FC(self.hidden)
        
        return out.view(-1, self.n_outputs) # batch_size X n_output

Paramater

Kita gunakan parameter yang terdiri dari berikut ini

# parameters 
N_STEPS = 28
N_INPUTS = 28
N_NEURONS = 150
N_OUTPUTS = 10
N_EPHOCS = 50

Langsung saja kita panggil serta sekalian buat loss function dengan tipe cross entropy

# Model instance
model = ImageRNN(BATCH_SIZE, N_STEPS, N_INPUTS, N_NEURONS, N_OUTPUTS)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

Mari kita coba masukan data gambar kedalam model tersebut

inputs = images.view(-1,28,28) 
outputs = model(inputs)
print('output',torch.argmax(outputs,dim=1))
print('target',labels)

hasilnya bisa kalian lihat dengan hasil masih salah

output tensor([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
target tensor([8, 9, 7, 8, 0, 7, 9, 3, 9, 3, 3, 8, 6, 7, 0, 2, 5, 2, 0, 7, 6, 6, 9, 8,
        2, 7, 0, 3, 5, 5, 3, 5, 4, 1, 8, 9, 6, 6, 6, 7, 2, 9, 1, 8, 5, 0, 6, 0,
        0, 8, 1, 9, 4, 5, 1, 1, 3, 4, 2, 1, 3, 3, 7, 2])

Kalian jangan bingung dengan perintah

See also  Hasil Training Pytorch Backend MPS GPU M1 tidak akurat dan solusinya

torch.argmax(outputs,dim=1)

yang merupakan output dengan array jumlah 10, sehingga akan dicari nilai maksimal mengingat output dari model emang dibuat 10 array lihat saja perintah pada model diatas.

return out.view(-1, self.n_outputs) # batch_size X n_output

Kita bisa mengambil kesimpulan bahwa input dengan ukuran 28 x 28 akan dijadikan output 1 x 10 saja sehingga loss function yang digunakan berupa cross entropy.

Proses Training

Bila sudah siap semuanya, kita langsung lakukan proses training

loss_list = list()
for epoch in tqdm(range(N_EPHOCS)):
    train_running_loss = 0.0
    train_acc = 0.0
    model.train()
    # TRAINING ROUND
    for i, data in enumerate(trainloader):
        optimizer.zero_grad()
        # reset hidden states
        model.hidden = model.init_hidden() 
        # get the inputs
        inputs, labels = data
        inputs = inputs.view(-1, 28,28) 
        # forward + backward + optimize
        outputs = model(inputs)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
    loss_list.append(loss.item())
    print("epoch: ",epoch," loss: ",loss.item())

hasilnya kita plotkan saja langsung

#tampilkan grafik epoch untuk loss function
plt.figure()
plt.plot(np.array(loss_list))
plt.xlabel('epoch')
plt.ylabel('loss')
plt.title('Grafik Loss tiap epoch')
plt.show()

Proses Validasi

Sekarang kita lanjutkan dengan proses validasi menggunakan dataset testing dengan hasil sebagai berikut

#lakukan evaluasi
model.eval()
jumlah_benar = 0
jumlah_data = 0
for i, data in enumerate(tqdm(testloader)):
    inputs, labels = data
    inputs = inputs.view(-1, 28, 28)
    outputs = model(inputs)
    prediksi  = torch.argmax(outputs,dim=1)
    benar = (prediksi==labels).sum()
    jumlah_benar = jumlah_benar+benar
    jumlah_data = len(labels)+jumlah_data
acc = (jumlah_benar/jumlah_data)*100
acc = np.round(acc.item(),decimals=2)
print("\n akuarasi acc : ",acc," %")

akuarasi acc : 96.89 %

Dapat disimpulkan RNN untuk Image Recognition dapat digunakan untuk mengenail dataset MNIST

Catatan Init Hidden

Selain menggunakan init hidden bernilai ZEROS (torch.zeros(1, self.batch_size, self.n_neurons)) kalian juga bisa menggunakan bilangan random seperti return nn.init.kaiming_uniform_(torch.empty(1, self.batch_size, self.n_neurons))

 

Ref:

https://colab.research.google.com/github/dair-ai/pytorch_notebooks/blob/master/RNN_PT.ipynb#scrollTo=LaAmGhZT8CRX

 

You May Have Missed