
Identification of beef and pork- identifikasi daging babi dan sapi ada banyak teknik yang digunakan, salah satunya merujuk paper Identification of beef and pork using gray level cooccurrence matrix and probabilistic neural network (Clarita Magdalena, 2021). Disitu dijelaskan metode yang digunakan yaitu GLCM – gray level coocurance matrix, pembahasan mengenai bisa kalian bisa Ciri Fitur dengan GLCM Gray Level Coocurance Matrix
Dalam abstrak dijelaskan mengenai Desain/metode/pendekatan yaitu penerapan GLCM (sebagai ciri fitur) dan discrimator nya menggunakan Probabilistic Neural Network untuk melakukan klasifikasi. Adapun Hasil yang didapat dari pengujian dengan validasi silang k-fold dan confussion matrix ini menunjukkan bahwa ekstraksi fitur Gray Level Co-Occurrence Matrix dan Probabilistic Neural Network Classifier mendapatkan rata-rata akurasi 87%, presisi 83%, dan recall 90%.
Judul tersebut membuat kami mencoba untuk melakukan teknik Deep Learning yaitu ciri fitur yang semula menggunakan GLCM akan digantikan dengan Convolution Neural Network dengan jenis Mengenal Arsitektur LeNet serta menggunakan loss function berupa Cara menggunakan loss function Negative log likelihood loss nn.NLLLoss
Batasan masalah disini yaitu untuk Identification of beef and pork tanpa dicampur/di mixing walaupun dalam kasus realnya pasti antara daging sapi dan babi akan dicampur untuk menyamparkan daging babi yang harganya lebih murah. Karena keterbatasan dataset yang ada di kaggle tersedia hanya daging tanpa dicampur.
Dataset
Contents
Dataset untuk Identification of beef and pork, kami peroleh di kaggle.com yang disimpan pada folder train yaitu sapi dan babi. Untuk mempermudah seragam data, dimension yang digunakan untuk LeNet yaitu 100 x 100 dalam mode grayscale
def TransformKu(): transform = transforms.Compose([ transforms.Resize((100,100)), transforms.RandomRotation(10), transforms.ToTensor(), transforms.Grayscale(), transforms.Normalize((0.5),(0.5),(0.5))]) return transform
Mengingat serat setiap daging itu berbeda-beda maka agar tahan terhadap arah sudut perlu kita buat random rotate.
Persiapan dataset
Untuk persiapan dataset serta mempercepat proses loading dataset menjadi trainloader, saya pakai imagefolder saja dariapda membuat class turunan dari dataset. Kalian bisa baca Membuat Dataset untuk Training Deep Learning disitu ada 2 cara yang digunakan.
transform = TransformKu() #cara pertama train_path = 'train' dataset = datasets.ImageFolder(train_path,transform=transform)
Arsitektur LeNet
Arsitektur LeNet dipilih karena sederhana dan tidak butuh banyak komputasi. Perlu penyesuaian sedikit karena kita desain itu untuk ukuran 28×28 dan diubah untuk 100 x 100. Adapun untuk convolutional bisa dijabarkan berikut
ada 2 tahap convolutional yaitu
- x = self.conv1(x)
- x = self.act(x)
- x = self.pool(x)
tahap convolutional kedua yaitu
- x = self.conv2(x)
- x = self.act(x)
- x = self.pool(x)
Langkah selanjutnya dimasukan ke MLP terdiri dari 3 layer yang setiap layer dihubungkan dengan fungsi aktifasi bertipe ReLU
- x = self.L1(x)
- x = self.act(x)
- x = self.L2(x)
- x = self.act(x)
- x = self.L3(x)
- x = self.Log(x)
terakhir akan dimasukan ke nn.LogSoftmax(dim=1) karena kita menggunakan loss_fn = torch.nn.NLLLoss() jadi nanti outputnya itu ada 2 paramater dengan class 1: babi, dan class 2: sapi. Berikut detail dari arsitekturnya
class ModelLeNet(nn.Module): def __init__(self): super(ModelLeNet,self).__init__() #Here, we are plementing those layers which are having learnable parameters. #Start implementation of Layer 1 (C1) which has 6 kernels of size 5x5 with padding 0 and stride 1 self.conv1 = nn.Conv2d(in_channels=1,out_channels=6,kernel_size=(5,5)) #Start implementation of Layer 3 (C3) which has 16 kernels of size 5x5 with padding 0 and stride 1 self.conv2 = nn.Conv2d(in_channels = 6, out_channels = 16,kernel_size = (5,5)) #Start implementation of Layer 5 (C5) which is basically flattening the data #self.L1 = nn.Linear(256, 120) #untuk ukuran 28*28 #self.L1 = nn.Linear(400, 120) #untuk ukuran 32*32 self.L1 = nn.Linear(16*22*22, 120) #untuk ukuran 100*100 #Start implementation of Layer 6 (F6) which has 85 Linear Neurons and input of 120 self.L2 = nn.Linear(120,84) #Start implementation of Layer 7 (F7) which has 10 Linear Neurons and input of 84 self.L3 = nn.Linear(84,2) #artinya 2 output #We have used pooling of size 2 and stride 2 in this architecture self.pool = nn.AvgPool2d(kernel_size = 2, stride = 2) #We have used tanh as an activation function in this architecture so we will use tanh at all layers excluding F7. self.act = nn.ReLU() self.Log = nn.LogSoftmax(dim=1) #Now we will implement forward function to produce entire flow of the architecture. def forward(self,x): x = self.conv1(x) #We have used tanh as an activation function in this architecture so we will use tanh at all layers excluding F7. x = self.act(x) #Now this will be passed from pooling x = self.pool(x) #Next stage is convolution x = self.conv2(x) x = self.act(x) x = self.pool(x) #next we will pass from conv3, here we will not pass data from pooling as per Architecture # print(x.shape) #Now the data should be flaten and it would be passed from FC layers. x = x.view(x.size()[0], -1) # print(x.shape) x = self.L1(x) x = self.act(x) x = self.L2(x) x = self.act(x) x = self.L3(x) x = self.Log(x) return x
Saya kira untuk Identification of beef and pork sudah lebih dari cukup. Setelah semuanya sudah siap, kita persiapkan dataset loader yaitu jumlah batch dan shuffle (bila ingin random ditukar urutannya). Data training juga digunakan untuk testing
batch_size = 4 shuffle = True pin_memory = False num_workers = 0 train_loader = DataLoader(dataset=dataset, shuffle=shuffle, batch_size=batch_size,num_workers=num_workers,pin_memory=pin_memory) test_loader = DataLoader(dataset=dataset, shuffle=shuffle, batch_size=batch_size,num_workers=num_workers,pin_memory=pin_memory)
Untuk minimal accuracy yaitu 98% berikut aturan lebih lanjut
model = ModelLeNet() learning_rate = 0.001 optimizer = optim.Adam(model.parameters(),lr=learning_rate) loss_fn = torch.nn.NLLLoss() minimal_accuracy = torch.tensor([0.98])
Untuk mengetahui jumlah waktu yang diperlukan kita butuh tic() dan toc() sebagai timmer serta melakukan ploting hasil accuracy tiap epoch
list_accuracy = list() tic() for epoch in range(100): model.train() for i, batch_train in enumerate(train_loader,0): input_train,target_train = batch_train prediksi_train = model(input_train) loss_train = loss_fn(prediksi_train,target_train) loss_train.backward() optimizer.step() optimizer.zero_grad() i = i+1 total_betul = torch.tensor([0]) #valuasi model for i, batch_test in enumerate(test_loader,0): model.eval() input_test,target_test = batch_test prediksi_test = model(input_test) prediksi_test = torch.argmax(prediksi_test,dim=1) total_betul = total_betul+torch.sum(prediksi_test==target_test) accuracy = total_betul/len(dataset) list_accuracy.append({'acc':accuracy.detach().numpy()[0]}) print('epoch',epoch, accuracy) if accuracy>=minimal_accuracy: break print(toc()) list_accuracy = pd.DataFrame(list_accuracy) list_accuracy['acc'].plot()
Berikut hasil diperoleh Identification of beef and pork dengan CNN dengan waktu 37 detik
epoch 0 tensor([0.6400]) epoch 1 tensor([0.7400]) epoch 2 tensor([0.6800]) epoch 3 tensor([0.8000]) epoch 4 tensor([0.7800]) epoch 5 tensor([0.8600]) epoch 6 tensor([0.8000]) epoch 7 tensor([0.8400]) epoch 8 tensor([0.9600]) epoch 9 tensor([1.]) 37.24626220000209
Dari proses diatas dengan target 100 epoch tercapai pada epoch ke 10 (karena dimulai dari angka 0) setiap epoch arsitektur LeNet mampu melakukan perbaikan secara increment
Berikut tampilan hasil proses Identification of beef and pork
Bila dilihat secara umum serat tekstur antara sapi (lembut) dan babi (kasar). Tulisan ini hanya sebagai inspirasi saja bila kalian ingin riset yang serius tentu butuh banyak dataset atau bahkan akan mengembakan alat yang dapat membaca campuran daging tersebut??