In [ ]:
#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

In [ ]:
#@title MIT License
#
# Copyright (c) 2017 François Chollet
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the "Software"),
# to deal in the Software without restriction, including without limitation
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
# and/or sell copies of the Software, and to permit persons to whom the
# Software is furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

Klasifikasi Dasar: Klasifikasi gambar pakaian

Panduan ini bertujuan untuk membangun sebuah model neural network yang dapat mengklasifikasikan gambar pakaian, seperti sneaker dan baju. Tidak masalah apabila saat ini Anda belum memahami seluruh detail yang ada; Ini merupakan ringkasan singkat dari sebuah program Tensorflow lengkap dengan penjelasan detail dari setiap langkah-langkahnya.

Panduan ini menggunakan tf.keras, sebuah API tingkat tinggi untuk membangun dan melakukan training model di TensorFlow.


In [ ]:
try:
  # %tensorflow_version only exists in Colab.
  %tensorflow_version 2.x
except Exception:
  pass

In [ ]:
from __future__ import absolute_import, division, print_function, unicode_literals

# TensorFlow and tf.keras
import tensorflow as tf
from tensorflow import keras

# Helper libraries
import numpy as np
import matplotlib.pyplot as plt

print(tf.__version__)

Import dataset Fashion MNIST

Panduan ini menggunakan dataset Fashion MNIST yang memiliki 70,000 gambar hitam putih dalam 10 kategori pakaian. Tiap gambar menunjukan gambar dari satu tipe pakaian dalam resolusi rendah (28 x 28 pixel), seperti yang dapat dilihat disini:

Gambar 1. Sampel gambar dari dataset Fashion-MNIST (by Zalando, MIT License).
 

Dataset Fashion MNIST dibuat untuk menggantikan dataset MNIST klasik - yang seringkali dijadikan sebagai "Hello, World" dari program machine learning untuk computer vision. Dataset MNIST terdiri atas gambar angka tulisan tangan (0, 1, 2, dsb) dalam format yang identik dengan gambar pakaian yang akan digunakan dalam dataset Fashion MNIST.

Panduan ini menggunakan Fashion MNIST agar lebih bervariasi, data ini juga sedikit lebih menantang dibandingkan dengan MNIST biasa. Kedua dataset berukuran kecil dan biasa digunakan untuk melakukan verifikasi apakah sebuah algoritma bekerja sesuai dengan yang diinginkan. Kedua data ini merupakan titik awal yang bagus untuk melakukan test dan debug terhadap kode.

60,000 gambar digunakan sebagai data train dari model neural network dan 10,000 gambar digunakan untuk mengevaluasi seberapa akurat model dapat mengklasifikasikan gambar. Anda dapat mengakses dataset Fashion MNIST langsung dari TensorFlow. Import dan muat data dari Fashion MNIST langsung dari TensorFlow:


In [ ]:
fashion_mnist = keras.datasets.fashion_mnist

(train_images, train_labels), (test_images, test_labels) = fashion_mnist.load_data()

Dataset yang telah di muat akan mengembalikan empat nilai NumPy arrays:

  • Array train_images dan train_labels merupakan data yang digunakan oleh model untuk mempelajari pattern
  • Model diuji menggunakan test set, yaitu array test_images, dan test_labels.

Tiap gambar merupakan array berukuran 28x28, dengan nilai pixel yang berkisar antara 0 sampai dengan 255. Label dari data merupakan array bertipe bilangan integer, yang memiliki rentang nilai dari 0 sampai dengan 9. Nilai ini memiliki korespondensi dengan kelas pakaian sebagai berikut:

Label Class
0 T-shirt/top
1 Trouser
2 Pullover
3 Dress
4 Coat
5 Sandal
6 Shirt
7 Sneaker
8 Bag
9 Ankle boot

Setiap gambar memiliki satu label saja. Nama kelas tidak tersedia dalam dataset, simpan nama kelas tersebut disini. Hal ini akan berguna ketika kita akan melakukan plotting dari gambar tersebut:


In [ ]:
class_names = ['T-shirt/top', 'Trouser', 'Pullover', 'Dress', 'Coat',
               'Sandal', 'Shirt', 'Sneaker', 'Bag', 'Ankle boot']

Eksplorasi Data

Mari kita lakukan eksplorasi dari format dataset sebelum kita menggunakan data tersebut untuk membangun model. Kode berikut menunjukan bahwa terdapat 60,000 gambar di dalam training set, setiap gambar berukuran 28 x 28 pixel.


In [ ]:
train_images.shape

Selain terdapat 60,000 gambar, terdapat juga 60,000 label di dalam training set:


In [ ]:
len(train_labels)

Setiap label adalah bilangan integer antara 0 dan 9:


In [ ]:
train_labels

Terdapat 10,000 gambar di dalam test set. Gambar ini juga direpresentasikan sebagai 28 x 28 pixel:


In [ ]:
test_images.shape

Dan test set mengandung 10,000 label gambar:


In [ ]:
len(test_labels)

Melakukan preprocessing terhadap data

Data harus diolah terlebih dahulu sebelum digunakan untuk membangun model neural network. Jika Anda mengamati gambar pertama dalam training set, Anda akan melihat bahwa nilai pixel dari gambar memiliki rentang antara 0 sampai dengan 255:


In [ ]:
plt.figure()
plt.imshow(train_images[0])
plt.colorbar()
plt.grid(False)
plt.show()

Nilai pixel ini akan diubah menjadi rentang 0 sampai dengan 1 sebelum menggunakannya sebagai input dari model neural network. Untuk melakukan hal tersebut, nilai tersebut harus dibagi dengan 255. Perlu diperhatika bahwa training set dan testing set harus diolah dengan cara yang sama:


In [ ]:
train_images = train_images / 255.0

test_images = test_images / 255.0

Untuk memastikan bahwa data dalam format yang benar dan Anda siap untuk membangun dan melatih model neural network, mari kita tampilkan 25 gambar pertama dari training set dan menampilkan nama kelas di bawah dari tiap gambar.


In [ ]:
plt.figure(figsize=(10,10))
for i in range(25):
    plt.subplot(5,5,i+1)
    plt.xticks([])
    plt.yticks([])
    plt.grid(False)
    plt.imshow(train_images[i], cmap=plt.cm.binary)
    plt.xlabel(class_names[train_labels[i]])
plt.show()

Membangun model

Untuk dapat membuat sebuah model neural network, perlu dilakukan konfigurasi layer untuk model tersebut, sehingga proses kompilasi pada model dapat dilakukan.

Pengaturan layer

Komponen utama dari neural network adalah layer. Layer mengekstraksi representasi dari data yang masuk ke dalam layer-layer tersebut. Harapannya, representasi tersebut berguna untuk mengatasi permasalahan yang ingin diselesaikan.

Kebanyakan deep learning terdiri atas penggabungan layer-layer sederhana. Kebanyakan layer, seperti tf.keras.layers.Dense, memiliki parameter-parameter yang dipelajari ketika proses training dijalankan


In [ ]:
model = keras.Sequential([
    keras.layers.Flatten(input_shape=(28, 28)),
    keras.layers.Dense(128, activation='relu'),
    keras.layers.Dense(10, activation='softmax')
])

Layer pertama dalam model neural network ini, tf.keras.layers.Flatten, melakukan transformasi dari format gambar yang mulanya aray dua dimensi (28 x 28 pixel) menjadi aray satu dimensi (28 * 28 = 784 pixel). Bayangkan layer ini sebagai layar yang membuat pixel-pixel dalam gambar menjadi satu baris. Layer ini tidak memiliki parameter untuk dipelajari; layer ini hanya mengubah format dari data.

Setelah pixel diubah menjadi satu baris, model yang akan dibuat terdiri dari dua buah layer tf.keras.layers.Dense. Kedua layer ini terhubung secara penuh. Layer Dense yang pertama memiliki 128 node (atau neuron). Layer yang kedua (dan terakhir) memiliki 10 node softmax yang mengembalikan sebuah array dari 10 nilai probabilitas yang apabila dijumlahkan hasilnya adalah 1. Setiap node memiliki score yang mengindikasikan probabilitas bahwa gambar yang sedang diproses merupakan 1 dari 10 kelas label.

Proses kompilasi model

Sebelum model siap untuk di training, model ini memerlukan beberapa pengaturan tambahan. Pengaturan ini ditambahkan ketika proses kompilasi:

  • loss function —Fungsi ini menghitung seberapa akurat model ketika proses training dilakukan. Anda ingin meminimalisir nilai kerugian dari fungsi ini untuk "mengarahkan" model ke arah yang benar.
  • Optimizer —Optimizer mendefinisikan cara model untuk memperbarui modelnya berdasarkan data yang dilihat dan berdasarkan loss function-nya.
  • Metrics —Bagian ini digunakan untuk memantau langkah-langkah dalam proses training dan testing. Dalam contoh ini, digunakan akurasi, perbandingan gambar yang diklasifikasikan dengan tepat oleh model.

In [ ]:
model.compile(optimizer='adam',
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

Proses training dari model

Melakukan training terhadap model neural network memerlukan beberapa langkah sebagai berikut:

  1. Gunakan training data sebagai inputan untuk model. Dalam kasus ini, training data terdapat dalam array train_images dan train_labels.
  2. Model akan mempelajari untuk mengasosiaskan antara gambar dan label.
  3. Anda menyuruh model untuk membuat prediksi terhadap test set, dalam kasus ini, array test_images. Pastikan bahwa prediksi cocok dengan label yang terdapat di array test_labels.

Untuk memulai proses training, panggil method model.fit—dinamakan method fit karena method ini "membuat" model berdasarkan data training:


In [ ]:
model.fit(train_images, train_labels, epochs=10)

Ketika proses training model sedang dilakukan, loss metrics dan accuracy metrics ditampilkan. Model ini mencapai akurasi sekitar 0.88 (atau 88%) terhadap data training.

Evaluasi nilai dari akurasi

Selanjutnya, bandingkan bagaimana performansi dari model terhadap data test:


In [ ]:
test_loss, test_acc = model.evaluate(test_images,  test_labels, verbose=2)

print('\nTest accuracy:', test_acc)

Hasilnya adalah akurasi dari data test sedikit lebih kecil dibandingkan dengan akurasi model terhadap data training. Perbedaan antara akurasi dari data training dan data test memperlihatkan overfitting. Overfitting terjadi ketika performansi dari model machine learning lebih buruk untuk data baru yang belum pernah dilihat sebelumnya dibandingkan dengan data training.

Membuat prediksi

Dengan model yang telah dilatih menggunakan data training, Anda dapat menggunakan model tersebut untuk memprediksi berbagai gambar.


In [ ]:
predictions = model.predict(test_images)

Disini, model kita telah memprediksi label dari tiap gambar yang terdapat di data test. Mari lihat prediksi pertama dari model:


In [ ]:
predictions[0]

Prediksi dari gambar pertama dalam data test adalah array dengan 10 angka. Prediksi ini memperlihatkan "confidence" dari model terhadap 10 jenis pakaian. Kita dapat melihat label mana yang memiliki nilai confidence yang tinggi:


In [ ]:
np.argmax(predictions[0])

Jadi, model memprediksi bahwa gambar tersebut adalah ankle boot, atau class_names[9]. Dengan meninjau label test, dapat dilihat bahwa klasifikasi ini benar:


In [ ]:
test_labels[0]

Gambar berikut digunakan untuk melihat seluruh set dari prediksi 10 kelas.


In [ ]:
def plot_image(i, predictions_array, true_label, img):
  predictions_array, true_label, img = predictions_array, true_label[i], img[i]
  plt.grid(False)
  plt.xticks([])
  plt.yticks([])

  plt.imshow(img, cmap=plt.cm.binary)

  predicted_label = np.argmax(predictions_array)
  if predicted_label == true_label:
    color = 'blue'
  else:
    color = 'red'

  plt.xlabel("{} {:2.0f}% ({})".format(class_names[predicted_label],
                                100*np.max(predictions_array),
                                class_names[true_label]),
                                color=color)

def plot_value_array(i, predictions_array, true_label):
  predictions_array, true_label = predictions_array, true_label[i]
  plt.grid(False)
  plt.xticks(range(10))
  plt.yticks([])
  thisplot = plt.bar(range(10), predictions_array, color="#777777")
  plt.ylim([0, 1])
  predicted_label = np.argmax(predictions_array)

  thisplot[predicted_label].set_color('red')
  thisplot[true_label].set_color('blue')

Mari lihat gambar ke-0, prediksi, dan array prediksi. Label prediksi yang tepat berwarna biru dan label prediksi yang salah akan berwarna merah. Bilangan yang ada memberikan presentase (dari 100) untuk label yang diprediksi.


In [ ]:
i = 0
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i],  test_labels)
plt.show()

In [ ]:
i = 12
plt.figure(figsize=(6,3))
plt.subplot(1,2,1)
plot_image(i, predictions[i], test_labels, test_images)
plt.subplot(1,2,2)
plot_value_array(i, predictions[i],  test_labels)
plt.show()

Mari buat plot beberapa gambar dengan prediksinya. Perhatikan bahwa model dapat salah meskipun model sangat percaya diri dengan prediksinya.


In [ ]:
# Plot the first X test images, their predicted labels, and the true labels.
# Color correct predictions in blue and incorrect predictions in red.
num_rows = 5
num_cols = 3
num_images = num_rows*num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
  plt.subplot(num_rows, 2*num_cols, 2*i+1)
  plot_image(i, predictions[i], test_labels, test_images)
  plt.subplot(num_rows, 2*num_cols, 2*i+2)
  plot_value_array(i, predictions[i], test_labels)
plt.tight_layout()
plt.show()

Akhirnya, gunakan model yang telah dibuat untuk membuat prediksi terhadap sebuah gambar.


In [ ]:
# Grab an image from the test dataset.
img = test_images[1]

print(img.shape)

model-model tf.keras dioptimalisasi untuk membuat prediksi dalam sebuah batch, atau koleksi, dari contoh-contoh sekaligus. Sehingga, meskipun Anda menggunakan satu gambar, Anda harus menambahkan gambar tersebut ke dalam list:


In [ ]:
# Add the image to a batch where it's the only member.
img = (np.expand_dims(img,0))

print(img.shape)

Sekarang prediksi label yang tepat untuk gambar ini:


In [ ]:
predictions_single = model.predict(img)

print(predictions_single)

In [ ]:
plot_value_array(1, predictions_single[0], test_labels)
_ = plt.xticks(range(10), class_names, rotation=45)

model.predict mengembalikan list dari list—satu list untuk setiap gambar di dalam batch dari data. Lakukan prediksi untuk gambar dalam batch ini:


In [ ]:
np.argmax(predictions_single[0])

Dan model memprediksi label sesuai yang diharapkan.