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 Teks dengan TensorFlow Hub: Review Movie

Notebook ini mengklasifikasikan review film sebagai positif atau negatif menggunakan teks dari review tersebut. Hal ini merupakan contoh dari binary—atau klasifikasi dua kelas, sebuah permasalahan machine learning yang penting dan sering ditemukan.

Tutorial ini menunjukan penerapan dasar dari transfer learning menggunakan TensorFlow Hub dan Keras.

Kita akan menggunakan dataset IMDB yang terdiri atas teks review 50,000 film yang didapatkan dari Internet Movie Database. Data ini kemudian dipisah menjadi 25,000 review untuk proses training dan 25,000 untuk proses testing. Set data untuk training dan testing seimbang, artinya keduanya memiliki jumlah yang sama untuk review positif dan negatif.

Notebook ini menggunakan tf.keras, sebuah API tingkat tinggi untuk membangun dan melatih model dengan TensorFlow, dan TensorFlow Hub, sebuah library dan platform untuk melakukan transfer learning. Untuk tutorial teks klasifikasi menggunakan tf.keras lebih lanjut, lihat MLCC Panduan Klasifikasi Teks.


In [ ]:
import numpy as np
import tensorflow as tf

!pip install tensorflow-hub
!pip install tensorflow-datasets
import tensorflow_hub as hub
import tensorflow_datasets as tfds

print("Version: ", tf.__version__)
print("Eager mode: ", tf.executing_eagerly())
print("Hub version: ", hub.__version__)
print("GPU is", "available" if tf.config.experimental.list_physical_devices("GPU") else "NOT AVAILABLE")

Unduh dataset IMDB

Dataset IMDB dapat diperoleh di imdb reviews atau TensorFlow datasets. Kode berikut ini berfungsi untuk mengunduh dataset IMDB dalam komputer Anda (atau colab runtime)


In [ ]:
# Split the training set into 60% and 40%, so we'll end up with 15,000 examples
# for training, 10,000 examples for validation and 25,000 examples for testing.
train_validation_split = tfds.Split.TRAIN.subsplit([6, 4])

(train_data, validation_data), test_data = tfds.load(
    name="imdb_reviews", 
    split=(train_validation_split, tfds.Split.TEST),
    as_supervised=True)

Eksplorasi data

Mari kita pahami sejenak mengenai format dari data ini. Setiap data merupakan kalimat yang merepresentasikan review film dan label dari review tersebut. Kalimatnya belum di proses terlebih dahulu sebelumnya. Label merupakan bilangan integer bernilai 0 atau 1, dimana 0 menunjukkan review negatif, dan 1 review positif.

Mari kita lihat 10 data pertama.


In [ ]:
train_examples_batch, train_labels_batch = next(iter(train_data.batch(10)))
train_examples_batch

Let's also print the first 10 labels.


In [ ]:
train_labels_batch

Membangun Model

Model neural network dibuat dengan menggabungkan beberapa layer—hal ini membutuhkan beberapa keputusan arsitektural:

  • Bagaimana caranya untuk merepresentasikan teks?
  • Berapa banyak layer yang akan digunakan dalam model?
  • Berapa banyak hidden units yang digunakan tiap layer?

Dalam contoh kali ini, data input terdiri atas kalimat-kalimat. Label untuk diprediksi adalah nilai 0 atau 1.

Salah satu cara untuk merepresentasikan teks adalah dengan cara mengubah kalimat menjadi vektor. Kita dapat menggunakan pre-trained text embedding sebagai layer pertama, yang akan memberikan tiga kelebihan:

  • kita tidak perlu mengkhawatirkan tentang preprocessing teks
  • kita dapat memperoleh keuntungan dari transfer learning,
  • embedding text memiliki ukuran yang tetap, sehingga akan menyederhanakan proses.

Dalam contoh ini kita akan menggunakan pre-trained text embedding model dari TensorFlow Hub yang disebut google/tf2-preview/gnews-swivel-20dim/1.

There are three other pre-trained models to test for the sake of this tutorial: Terdapat tiga model pre-trained lainnya yang akan dicoba dalam tutorial ini:

Mari kita buat layer Keras pertama yang menggunakan model Tensorflow Hub untuk menyisipkan kalimat, dan mencoba model tersebut dengan beberapa contoh input. Perhatikan bahwa berapapun panjang dari teks input, bentuk output dari embbeding adalah : (num_examples, embedding_dimension).


In [ ]:
embedding = "https://tfhub.dev/google/tf2-preview/gnews-swivel-20dim/1"
hub_layer = hub.KerasLayer(embedding, input_shape=[], 
                           dtype=tf.string, trainable=True)
hub_layer(train_examples_batch[:3])

Mari kita buat model lengkapnya:


In [ ]:
model = tf.keras.Sequential()
model.add(hub_layer)
model.add(tf.keras.layers.Dense(16, activation='relu'))
model.add(tf.keras.layers.Dense(1, activation='sigmoid'))

model.summary()

Layer-layer yang dihubungkan secara berurutan untuk membangun model klasifikasi:

  1. Layer yang pertama adalah layer TensorFlow Hub. Layer ini digunakan sebagai model tersimpan yang telah dilatih sebelumnya untuk memetakan kalimat menjadi vektor. Model pre-trained text embedding yang digunakan (google/tf2-preview/gnews-swivel-20dim/1) memisahkan kalimat menjadi token, menyisipkan setiap token dan kemudian menggambungkan sisipan tersebut. Dimensi keluaran dari layer ini: (num_examples, embedding_dimension).
  2. Vektor dengan panjang yang sama ini kemudian disalurkan melalui layer yang saling terhubung seluruhnya (Dense) dengan 16 hidden unit.
  3. Layer terakhir adalah masing-masing terhubung ke satu node output. Menggunakan fungsi aktivasi sigmoid, akan menghasilkan nilai antara 0 dan 1, merepresentasikan probabilitass, atau tingkat kepercayaan diri dari model.

Mari lakukan kompilasi terhadap model.

Loss function dan optimizer

Sebuah model memerlukan sebuah loss function dan sebuah optimizer sebelum proses training dilakukan. Karena ini merupakan permasalahan klasifikasi biner dan output dari model adalah probabilitas (sebuah layer satu unit dengan aktivasi sigmoid), kita akan menggunakan loss function berupa binary_crossentropy.

Ini berupakan satu-satunya pilihan dari loss function, Anda dapat, misalnya, memilih mean_squared_error. Akan tetapi, secara umum, binary_crossentropy lebih baik ketika berhadapat dengan probablitas—fungsi ini menghitung jarak antara distribusi dari probabilitas, atau dalam kasus ini, antara distribusi yang sebenarnya dengan prediksi.

Nanti, ketika kita sedang menghadapi permasalahan regresi (misalkan, memprediksi harga dari sebuah rumah), kita akan melihat bagaimana kita menggunakan loss function lain yang disebut mean squared error.

Sekarang, konfigurasi model untuk menggunakan optimizer dan loss function:


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

Melatih Model

Latih model untuk 20 epoch dalam batch kecil berjumlah 512 sampel. Ini artinya 20 iterasi untuk seluruh sampel dalam tensor x_train dan y_train. Ketika proses training, amati nilai kerugian (loss) dan akurasi terhadap 10,000 sampel dari set validasi:


In [ ]:
history = model.fit(train_data.shuffle(10000).batch(512),
                    epochs=20,
                    validation_data=validation_data.batch(512),
                    verbose=1)

Evaluasi model

Dan mari kita lihat bagaimana performa dari model. Dua nilai akan dikembalikan. Nilai kerugian (sebuah angka yang merepresentasikan error, semakin kecil nilainya semakin baik), dan akurasi.


In [ ]:
results = model.evaluate(test_data.batch(512), verbose=2)

for name, value in zip(model.metrics_names, results):
  print("%s: %.3f" % (name, value))

Teknik yang sederhana ini memperoleh akurasi sekitar 87%. Dengan teknik yang lebih tinggi, akurasi model dapat mencapai 95%.

Pustaka lanjutan

Untuk cara kerja yang lebih umum untuk bekerja dengan input string dan untuk analisis yang lebih detail tentang akurasi dan loss ketika proses training, lihat disini.