Anda di halaman 1dari 27

Open in app Get started

Sign in to Medium with Google

Hafizhan Aliady Afif Follow Suhardi Aras


suhardi.1172@students.amikom.ac.id
Apr 28, 2020 · 11 min read

Continue as Suhardi
Save

Membuat klasifikasi gambar(images),


Menggunakan Keras-Tensorflow (tf.keras) di
Python

Photo by John-Mark Smith on Unsplash


NB: Sebelum dimulai, Artikel ini sudah di perbaharui per 1 Januari 2022
Open in app Get started

Assalamualaikum, Setelah lama tidak menulis artikel dan tutorial, akhirnya diriku ke-
pikiran juga buat nulis ini karena ini cukup penting sih tapi kadang suka lupa, jadi
akhirnya cari-cari lagi materi tentang ini di internet, jadi daripada nanti diriku mencari-
cari lagi dan bingung sendiri mungkin sebaiknya bikin tutorial nya saja sekalian. Biar tidak
bingung.dan di sini tensorflow yang digunakan adalah tensorflow 2.1 yang terbaru. sudah
tidak menggunakan keras lagi. Kemudian mari kita masuk ke outline nya dulu.

Dalam tulisan ini akan mencakup beberapa hal:


• Image classification, apa itu ?

• Apa yang perlu disiapkan untuk membuat sebuah image classifier ?

• Mempersiapkan dataset

• Membuat Pipeline untuk input dataset

• Membangun Model Convolutional Neural Network,

• Menggunakan Arsitektur Model CNN yang sudah ada.

• Meng-Compile Model

• Model Training

• Model Save

• Model Evaluation

• Create Predict Function.

Let’s Start! Image Classification, Apa itu ?


Ya klasifikasi sebuah citra, berdasarkan klasifikasi yang kita buat. dan Ya, klasifikasi
gambar merupakan salah satu metode machine learning / artificial intelligence yang
dapat digunakan untuk mendeteksi sebuah gambar dengan cepat. intinya sih misalnya
kita punya kebun bunga, terus kita panen semua tuh bunganya. Nah kita agak kesulitan
Open in app Get started
buat mengelompokkan bunganya karena ada bunga yang hampir mirip dan bunganya itu
banyak banget. jadi daripada kita kelompokin bunganya satu satu, mungkin sebaiknya
kita membuat mesin untuk mengelompokan bunga tersebut sehingga kita dapat lebih
mudah untuk pengelompokannya dan menjadi lebih efisien. Ya gitu aja sih gambarannya.

Jika membutuhkan pendalaman lebih lanjut mengenai image classification kalian bisa
mengunjungi Youtube/ Cari di Google. Pasti sudah banyak sih referensi nya. Dan tujuan
dari menulis ini adalah karena tensorflow sudah mengeluarkan versi 2.x maka sudah
saatnya upgrade dari yang sebelumnya menggunakan keras menjadi tf.keras dan
dalam prosesnya modul tf.keras ini lebih efisien dibandingkan dengan sebelumnya.

Dan mungkin setelah ini saya akan pindah ke pytorch wkwkwk ~

Oke mari kita mulai

Yang perlu disiapkan!


Beberapa kebutuhan untuk membuat image classifier merupakan kebutuhan yang tidak
murah, karena img classifier membutuhkan performa komputasi yang cukup tinggi agar
dapat berjalan dengan lancar.Namun Kita dapat menggunakan Google Code Lab (Colab)
untuk melakukannya.

Hal yang perlu disiapkan:


• benda atau sesuatu objek yang ingin diklasifikasikan.

• Komputer / PC yang dapat mengakses internet

• Google Account untuk mengakses Google Colab (Pake di lokal juga bisa)

• Pengetahuan dasar mengenai Python

Library yang digunakan


• Tensorflow ≥ 2.2 ( tested on tf 2.7)
• Numpy
Open in app Get started

• Scikit-learn

• PILLOW untuk image library

Mempersiapkan Data-set
Ya kita siapkan dulu data-setnya, Di sini kita gunakan contoh gambar/ image bunga dari
kaggle saja biar enak untuk datanya bisa klik di sini .

Pertama tama kita extract terlebih dahulu datanya, lalu treedir nya akan seperti ini. saat
data pertama kali di extract.

└── flowers
├── daisy
├── dandelion
├── flowers
│ ├── daisy
│ ├── dandelion
│ ├── rose
│ ├── sunflower
│ └── tulip
├── rose
├── sunflower
└── tulip

Dalam proses yang pertama ini, kita ingin membagi datanya menjadi 3 bagian. yaitu train,
test, dan validation. dengan proporsi (80,10,10).

Kemudian, pada proses ini kita ingin membagi datanya menjadi seperti ini.

├── dataset
│ ├── test
│ │ ├── daisy
│ │ ├── dandelion Open in app Get started
│ │ ├── rose
│ │ ├── sunflower
│ │ └── tulip
│ ├── train
│ │ ├── daisy
│ │ ├── dandelion
│ │ ├── rose
│ │ ├── sunflower
│ │ └── tulip
│ └── validation
│ ├── daisy
│ ├── dandelion
│ ├── rose
│ ├── sunflower
│ └── tulip

Berikut untuk kode nya.


Open in app Get started

Mempersiapkan variabel global untuk training


Dibagian ini kita akan menentukan seberapa banyak jumlah epoch untuk proses training,
input dimension, batch_size. dll
# Parameter input untuk network Open in app Get started
dim = (150, 150)
channel = (3, )
input_shape = dim + channel

# Batch size
batch_size = 16

# Epoch
epoch = 10

Mempersiapkan dataset pipeline dan augmentation Untuk proses


pembuatan dataset
Dataset pipeline merupakan perintah untuk melakukan ekstraksi data yang berupa
images/citra digital, yang berasal dari sebuah folder menjadi sebuah array yang dapat
dibaca oleh tensorflow, fungsi yang digunakan adalah from

tensorflow.keras.preprocessing.image import ImageDataGenerator

Fungsi tersebut merupakan Image data generator sehingga kita mengenerate data image
dari sebuah file / folder yang telah kita buat sebelumnya. pada bagian ini kita dapat
menentukan generator / augmentasi seperti apa yang dapat dilakukan.

Untuk bacaan lebih lanjut dapat mengunjungi tautan referensi berikut:


- https://blog.keras.io/building-powerful-image-classification-models-using-very-little-
data.html
- https://keras.io/preprocessing/image/

Pertama tama kita mendefinisikan terlebih dahulu bagaimana transformasi data yang
akan digunakan.

train_datagen = ImageDataGenerator(rescale=1. / 255,


shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
val_datagen = ImageDataGenerator(rescale=1. / 255, Open in app Get started
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1. / 255,


shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)

Pada perintah diatas kita melakukan

• Rescaling data menjadi 1/255.

• Shearing image skala 0.2

• Zooming image dengan range 0.2

• dan melakukan Horizontal flip

Sehingga contohnya akan seperti ini


Src: https://towardsdatascience.com/machinex-image-data-augmentation-using-keras-b459ef87cd22
Open in app Get started

Membuat flow datanya


Setelah mendefinisikan generatornya, selanjutnya kita mendefinisikan darimana sumber
datanya berasal. Misalkan pada project kali ini kita menggunakan data yang berasal dari
folder (dictionary) sehingga code yang digunakan adalah sebagai berikut:
pada code diatas, kita menggunakan flow from dir dimana fungsi tersebut mengarahkan
Open in app Get started
kita kepada folder set yang telah kita buat sebelumnya. di mana :

• target size = dimensi dari citra yang akan digunakan dalam proses training

• batch size = banyaknya citra yang dimasukan dalam setiap steps training.

• class mode = metode pemilihan klasifikasi


# binary = [1,0,0,0,0] [0,1,0,0,0] [0,0,1,0,0] [0,0,0,1,0] [0,0,0,0,1]

# categorical = 1,2,3,4,5

• shuffle = data didalam folder tersebut diacak sehingga tidak sesuai urutan yang ada
seperti urutan alfabetik.

Transformasi data generator menjadi tf.data


Pada proses ini kita akan melakukan transformasi variabel train_generator dan lainnya
menjadi tf data, kenapa menggunakan tf.data karena tf.data merupakan tipe variabel
generator yang cocok dengan tf.keras sehingga sangat optimal dalam pembacaan data
yang dilakukan dalam proses training dibandingkan hanya menggunakan generator dari
keras itu sendiri. Untuk lebih lanjut dapat dibaca di sini. Lalu berikut penerapannya.
def tf_data_generator(generator, input_shape): Open in app Get started
num_class = generator.num_classes
tf_generator = tf.data.Dataset.from_generator(
lambda: generator,
output_types=(tf.float32, tf.float32),
output_shapes=([None
, input_shape[0]
, input_shape[1]
, input_shape[2]]
,[None, num_class])
)
return tf_generator

train_data = tf_data_generator(train_generator, input_shape)


test_data = tf_data_generator(test_generator, input_shape)
val_data = tf_data_generator(val_generator, input_shape)

Membuat Struktur Convolutional Neural Network


Setelah membuat dataset generator, selanjutnya kita melakukan membuat jaringan nerual
network. Namun karena kita terlalu malas maka kita dapat menggunakan network yang
sudah ada. pada project ini kita menggunakan Mobilenet V2 untuk paper terkait dapat
dibaca di sini. Kemudian untuk pilihan network-network yang sudah ada bisa dilihat di
sini.

Pertama-tama kita mendefinisikan terlebih dahulu base-model kita / yang akan di


gunakan pada project ini.

from tensorflow.keras.applications import MobileNetV2

# get base models


base_model = MobileNetV2(
input_shape=input_shape,
include_top=False,
weights='imagenet',
classes=num_class,
)
Di mana :
Open in app Get started

• Input_shape = merupakan dimensi dari gambar yang akan kita gunakan/ input dari
citra

• Include top = adalah perintah untuk menyertakan apakah model yang digunakan
akan disertakan dengan top layer dari arsitektur network tersebut atau misalkan top
network tersebut memiliki 3 node yaitu : flatten layer, layer dengan 1024 node dan
fungsi aktivasinya, lalu prediction node dimana jumlah node sesuai dengan
banyaknya jumlah kelas.
Dikarenakan jumlah kelas pada imagenet adalah 1000 maka ini tidak cocok dengan
jumlah kelas yang kita miliki yaitu hanya 5. sehingga include top di sini adalah false.

• Weights = adalah bobot dari masing-masing layer yang sudah di training berdasarkan
bobot imagenet. Kita juga bisa meniadakan ini dengan menggunakan None Namun
ketika tidak menggunakan pre-trained weight proses training kita akan lebih lama
karena initial value dari weight nya random sehingga perlu banyak penyesuaian
terhadap data yang akan kita gunakan.

• Classes = adalah jumlah class yang kita miliki

Setelah berhasil maka base-model sudah terbentuk dan selanjutnya adalah menambahkan
top layer yang akan kita definisikan karena kita set false pada base model di atas.

from tensorflow.keras import layers,Sequential


from tensorflow.keras.models import Model

#Adding custom layers


x = base_model.output
x = layers.GlobalAveragePooling2D()(x)
x = layers.Dropout(0.2)(x)
x = layers.Dense(1024, activation="relu")(x)

predictions = layers.Dense(num_class, activation="softmax")(x)


model = Model(inputs=base_model.input, outputs=predictions)
Kita telah menambahkan top-layer kedalam network dan variabel yang digunakan adalah
Open in app Get started
model. Kemudian kita dapat melihat keseluruhan network dengan
menggunakan model.summary()

Bisa kita lihat bahwa top layer yang kita definisikan sudah masuk kedalam model. Dan
model bisa kita compile sehingga dapat digunakan untuk training.

Compile model

# Compile the model


print('Compiling Model')
model.compile(optimizer='adam',
loss='categorical_crossentropy',
metrics=['accuracy'])

Pada proses ini kita meyusun model menjadi siap dilakukan proses training. Dimana
variabel yang digunakan adalah-
sebagai berikut:

• Optimizer = merupakan metode optimasi yang digunakan.

• loss = adalah metode pengukuran nilai loss berdasarkan pada nilai apa. karena
Membuat flow datanya kita menggunakan categorical sehingga pada nilai loss ini kita
juga menggunakan categorical loss.
Open in app Get started

• Metrics = Nilai matriks yang diukur pada project ini kita menggunakan nilai akurasi
sebagai nilai pengukurannya. Untuk lainnya bisa baca di sini

Visualisasi Model
Kita bisa memvisualisasikan model menggunakan perintah berikut.

model_viz = tf.keras.utils.plot_model(model,
to_file='model.png',
show_shapes=True,
show_layer_names=True,
rankdir='TB',
expand_nested=True,
dpi=55)
model_viz

Dan hasilnya akan seperti ini.


Dan itu hasilnya sangat panjang. atau kalian dapat membuka filenya dengan nama file
Open in app Get started
model.png

Proses Training Model


Setelah membuat model selanjutnya adalah melakukan proses training, dimana proses
training ini merupakan proses dimana machine learning bekerja sehingga algoritma yang
sudah kita definisikan dapat mengingat pola dari masing masing kelas pada data yang kita
train. Untuk perintahnya adalah menggunakan perintah berikut.

EPOCH = 5
history = model.fit(x=train_data,
steps_per_epoch=len(train_generator),
epochs=EPOCH,
validation_data=val_data,
validation_steps=len(val_generator),
shuffle=True,
verbose = 1)

Dimana:

• X = merupakan data generator yang sudah kita proses sehingga menjadi tf-data ini
merupakan data training.

• Steps per epoch merupakan banyaknya steps / langkah untuk menyelesaikan 1 epoch,
disini 1 steps merupakan 1 batch_size / 1 batch_size adalah 16 citra, seperti yang
sudah di definisikan diatas.

• epoch = banyaknya proses iterasi/ pengulangan pada training

• val_data = validation data yang dievaluasi pada setiap epoch berakhir

• val_steps = sama seperti step per epoch


• shuffle = adalah dimana masing masing batch pada generator diacak sehingga data
Open in app Get started
tidak akan urut.

• Verbose =menampilkan progress bar dimana 1 karena kita dapat melihat proses dan
hasil dari setiap steps seperti gambar dibawah nanti.

Untuk keterangan lebih lanjut dapat dibaca disini.

Kemudian untuk contoh proses training nya akan seperti ini.

Mari kita tunggu sampai proses training selesai. Dari hasil diatas bisa kita baca bahwa
akurasi pada data training adalah 0.70 dan nilai lossnya adalah 0.91, Kemudian untuk
data validasinya adalah 0.544 dan nilai lossnya adalah 2.388. Namun ini baru iterasi
pertama. Sehingga kita bisa menunggu untuk iterasi berikutnya / hingga model selesai
dilatih dengan 5 iterasi.

Train for 262 steps, validate for 52 steps


Epoch 1/5
262/262 [==============================] - 500s 2s/step - loss: 0.8980
- accuracy: 0.7101 - val_loss: 5.8360 - val_accuracy: 0.3809
Epoch 2/5
262/262 [==============================] - 477s 2s/step - loss: 0.6339
- accuracy: 0.7850 - val_loss: 4.2796 - val_accuracy: 0.3954
Epoch 3/5
262/262 [==============================] - 501s 2s/step - loss: 0.5341
- accuracy: 0.8178 - val_loss: 3.0686 - val_accuracy: 0.5417
Epoch 4/5
262/262 [==============================] - 502s 2s/step - loss: 0.4666
- accuracy: 0.8382 - val_loss: 1.5857 - val_accuracy: 0.7920
Epoch 5/5
262/262 [==============================] - 517s 2s/step
Open in - loss:Get0.4520
app started
- accuracy: 0.8497 - val_loss: 4.1316 - val_accuracy: 0.5816

Dan hasil training nya adalah seperti itu, Hasil tersebut rupanya tidak bagus ternyata
untuk model ini. Di mana

Dimana nilai loss pada data validasi adalah cenderung tidak stabil. Sehingga bisa dibilang
model ini overfit terhadap data training namun belum tentu. Perlu percobaan lebih lanjut
apakah model ini overfit atau tidak.
Open in app Get started

Begitu juga dengan nilai akurasi nya. Di mana nilai akurasi untuk data validasi cenderung
tidak stabil sehingga model ini kurang baik. Maka diperlukan penelitian lebih lanjut untuk
mencari model yang terbaik. Bisa dilakukan training ulang atau mengganti dengan model
/ network yang baru.

Simpan Model yang sudah di training


Setelah melakukan proses training, selanjutnya adalah melakukan save pada model.

MODEL_BASE_PATH = "model"
PROJECT_NAME = "medium_project"
SAVE_MODEL_NAME = "model.h5"
save_model_path = os.path.join(MODEL_BASE_PATH, PROJECT_NAME,
SAVE_MODEL_NAME)

if os.path.exists(os.path.join(MODEL_BASE_PATH, PROJECT_NAME)) ==
False:
os.makedirs(os.path.join(MODEL_BASE_PATH, PROJECT_NAME))

print('Saving Model At {}...'.format(save_model_path))


model.save(save_model_path,include_optimizer=False)
Pada bagian model.save(...,include_optimizer=False) ini merupakan agar si tensorflow
Open in app Get started
tidak menyimpan keadaan optimizer pada saat terakhir disimpan, Ini agar dapat
menghemat media penyimpanan dan mempermudah dalam proses deployment. Dan
contoh perbandingannya adalah sebagai berikut:

Model pertama merupakan model.h5 yang tanpa optimizer dan model2.h5 adalah model
dengan optimizer didalamnya. Sehingga perbedaannya adalah 3 kali lipat dari model
tanpa optimizer. ini sangat menghemat penyimpanan.

Evaluasi model menggunakan data testing


Pada bagian ini kita melakukan testing menggunakan data test. Di mana, data test ini
tidak diikut sertakan ke dalam proses training. Berikut adalah perintahnya:

loss, acc =
model.evaluate(test_data,steps=len(test_generator),verbose=0)
print('Accuracy on training data: {:.4f} \nLoss on training data:
{:.4f}'.format(acc,loss),'\n')

loss, acc =
model.evaluate(test_data,steps=len(test_generator),verbose=0)
print('Accuracy on test data: {:.4f} \nLoss on test data:
{:.4f}'.format(acc,loss),'\n')

dan hasilnya adalah sebagai berikut :

Accuracy on training data: 0.5756


Loss on training data: 4.3997

Accuracy on test data: 0.5526


Loss on test data: 4.7524
Open in app Get started

Dari hasil tersebut dilihat bahwa model cukup stabil di kedua data sehingga dapat
disarankan untuk melakukan training lagi atau dapat mencari algoritma / model yang
lain seperti inception_v2 ataupun inception_resnet.

Untuk kode lengkapnya, bisa dilihat di notebook ini pada notebook ini saya contohkan juga
menggunakan efficient-net dimana efficient net merupakan model yang terbaik pada
#SOTA-1 Image-net.
Open in app Get started

Membuat Fungsi Prediksi


Setelah kita membuat model dan melakukan training model langkah selanjutnya adalah
membuat fungsi prediksi. Sehingga jika kita memiliki data baru diluar data train test
validasi. maka kita dapat dengan mudah memprediksinya.
Open in app Get started

Langkah pertama yang dilakukan adalah melakukan definisi variabel global.

import requests
from io import BytesIO

from PIL import Image


import numpy as np

# Parameters
input_size = (150,150) # Bisa kalian ganti

#define input shape


channel = (3,)
input_shape = input_size + channel

#define labels
labels = ['daisy', 'dandelion', 'rose', 'sunflower', 'tulip']

Dimana kita input kan sesuai dengan nilai yang sama seperti pada saat proses training.
untuk label nya bisa kita urutkan sesuai dengan abjad atau pada saat proses training. label
nya disimpan seperti gambar berikut :

Lalu selanjutnya adalah mendefinisikan fungsi pre-process, dimana fungsi ini adalah
mengubah sebuah citra menjadi sebuah array yang cocok untuk masuk kedalam model
Open in app Get started
yang sudah kita latih.

def preprocess(img,input_size):
nimg = img.convert('RGB').resize(input_size, resample= 0)
img_arr = (np.array(nimg))/255
return img_arr

def reshape(imgs_arr):
return np.stack(imgs_arr, axis=0)

fungsi diatas merupakan fungsi mengubah image menjadi array dimana image diubah
menjadi frormat RGB kemudian dilakukan resize dengan metode interpolasi Nearest-
neighbor default dari library tersebut.

Setelah itu melakukan reshape array yang awalnya adalah 3 dimensi, menjadi 4 dimensi,
atau bisa disebut tensor.

Kemudian selanjutnya adalah melakukan load model yang sudah di training. Load model
tersebut dapat lakukan dengan menggunakan perintah berikut.

from tensorflow.keras.models import load_model

MODEL_PATH = 'model/medium_project/model.h5'
model = load_model(MODEL_PATH,compile=False)

Setelah model yang sudah dilatih telah berhasil dimuat. maka selanjutnya adalah
melakukan prediksi terhadap sebuah gambar. Misalnya kita memiliki contoh gambar
berikut :
Open in app Get started

219 9
Lalu kemudian perintahnya adalah sebagai berikut:

# read image
im = Image.open('contoh_prediksi.jpg')
X = preprocess(im,input_size)
X = reshape([X])
y = model.predict(X)

print( labels[np.argmax(y)], np.max(y) )


About Help Terms Privacy

Di mana, pada perintah di atas kita membuka image / citra . Kemudian, kita melakukan
Get the Medium
preprocess app menjadi sebuah numpy.array yang kemudian direshape menjadi sebuah
imagenya
Open in app Get started
tensor. Setelah itu memprediksi termasuk bunga apakah gambar tersebut.

Hasilnya adalah seperti gambar diatas. Variabel y merupakan nilai dari hasil prediksi yang
menghasilkan banyak nilai. Di mana nilai-nilai tersebut adalah nilai dari masing-masing
kategori.

Kemudian kita mencari nilai ter-besarnya, yaitu pada kolom ke 4 yang merupakan kelas tulip
berdasarkan label yang sudah di definisikan di atas. dan dengan nilai probabilitas ~0.91-.

Untuk kode lengkap pada proses prediksi, dapat dilihat pada notebook berikut.
Open in app Get started

Sekian, untuk story kali ini.


Jika memiliki pertanyaan feel free bertanya ke hafizhan.afif@gmail.com
Untuk keseluruhan code nya bisa clone dari github disini
Open in app Get started

Anda mungkin juga menyukai