Transfer Learning dan Fine Tuning – 3

Melanjutkan dari modul sebelumnya, pada modul ini kita akan membuat model dengan menggunaan MobileNetV2.

Seperti yang kita pahami, setiap model memerlukan input size tertentu, MobileNetV2 menggunakan ukuran 128 x 128.

Untuk menggunakan MobileNet, gunakan perintah tf.keras.applications.MobileNetV2. Parameter yang dibutuhkan adalah

  • input_shape, yaitu ukuran input yang akan diisi dengan variable yang telah definisikan sebelumnya.
  • include_top, boolean True atau False, seperti yang sudah dibahas sebelumnya, pre-trained model memiliki base dan top. Karena kita akan membuat klasifikasi sendiri, maka bagian top akan dibuat sendiri, oleh karena itu diisi dengan False.
  • weights, adalah nama dataset yang digunakan untuk model training. Pada tutorial digunakan imagenet.
IMG_SHAPE = (128, 128, 3)

base_model = tf.keras.applications.MobileNetV2(input_shape=IMG_SHAPE, include_top=False, weights="imagenet")

Ketika perintah dijalankan, model akan didownload. Setelah download selesai, model dapat digunakan.

Downloading data from https://storage.googleapis.com/tensorflow/keras-applications/mobilenet_v2/mobilenet_v2_weights_tf_dim_ordering_tf_kernels_1.0_128_no_top.h5
9412608/9406464 [==============================] - 0s 0us/step

JIka Anda lihat model summary, dapat dilihat architecture dari model sangat kompleks. Pada tutorial ini kita potong hasil summarynya, karena terlalu panjang.

base_model.summary()
Model: "mobilenetv2_1.00_128"
__________________________________________________________________________________________________
Layer (type)                    Output Shape         Param #     Connected to                     
==================================================================================================
input_1 (InputLayer)            [(None, 128, 128, 3) 0                                            
__________________________________________________________________________________________________
Conv1_pad (ZeroPadding2D)       (None, 129, 129, 3)  0           input_1[0][0]                    
__________________________________________________________________________________________________
Conv1 (Conv2D)                  (None, 64, 64, 32)   864         Conv1_pad[0][0]                  
__________________________________________________________________________________________________
bn_Conv1 (BatchNormalizationV1) (None, 64, 64, 32)   128         Conv1[0][0]                      
__________________________________________________________________________________________________
Conv1_relu (ReLU)               (None, 64, 64, 32)   0           bn_Conv1[0][0]                   
__________________________________________________________________________________________________
expanded_conv_depthwise (Depthw (None, 64, 64, 32)   288         Conv1_relu[0][0]                 
______________________________________________________________________________
......
......
...... Summary model di truncate .....      
......
......  __________________________________________________________________________________________________
block_16_project_BN (BatchNorma (None, 4, 4, 320)    1280        block_16_project[0][0]           
__________________________________________________________________________________________________
Conv_1 (Conv2D)                 (None, 4, 4, 1280)   409600      block_16_project_BN[0][0]        
__________________________________________________________________________________________________
Conv_1_bn (BatchNormalizationV1 (None, 4, 4, 1280)   5120        Conv_1[0][0]                     
__________________________________________________________________________________________________
out_relu (ReLU)                 (None, 4, 4, 1280)   0           Conv_1_bn[0][0]                  
==================================================================================================
Total params: 2,257,984
Trainable params: 2,223,872
Non-trainable params: 34,112

Seperti yang sudah dibahas pada modul bagian pertama, untuk Transfer Learning, base model akan kita freeze.

Jika base model tidak di freeze, model akan ditraining ulang dan nilai weight akan berubah. Tentu ini bukan tujuan dari tutorial ini.

base_model.trainable = False

Langkah berikutnya adalah membuat custom head sesuai kebutuhan dari model yang akan kita kembangkan, pada tutorial adalah klasifikasi anjing dan kucing.

Untuk membuat custom head, kita perlu memeriksa output size dari base network, informasi tersebut digunakan untuk membuat layer pada custom head.

base_model.output
<KerasTensor: shape=(None, 4, 4, 1280) dtype=float32 (created by layer 'out_relu')>

Dapat dilihat, shape output adalah 4 x 4 x 1280. Ukuran ini tidak sama dengan custom head yang akan kita buat. Solusinya adalah dengan menggunakan global average pooling layer, konsepnya mirip dengan max pooling layer pada CNN.

Global average pooling akan menggunakan nilai rata-rata.

global_average_layer = tf.keras.layers.GlobalAveragePooling2D()(base_model.output)

Langkah selanjutnya adalah membuat output layer (prediction layer). Karena kita melakukan binary classification, maka nilai units yang diperlukan adalah 1, dan activation function yang digunakan adalah sigmoid. Input untuk layer output adalah global_average layer.

prediction_layer = tf.keras.layers.Dense(units=1, activation='sigmoid')(global_average_layer)

Sampai disini, custom head telah selesai didefinisikan. Langkah selanjutnya adalah membuat model dengan menggabungkan base model dengan custom head.

Untuk menggabungkan dua model, kita gunakan perintah keras.models.Model, dimana kita bisa menentukan input dan output layer. Input adalah base model dan output adalah prediction layer.

model = tf.keras.models.Model(inputs=base_model.input, outputs=prediction_layer)

JIka kita periksa model dengan perintah model.summary(), maka dapat dilihat pada akhir summary terdapat custom head yang kita buat pada langkah diatas.

....
....
....
global_average_pooling2d (Globa (None, 1280)         0           out_relu[0][0]                   
__________________________________________________________________________________________________
dense (Dense)                   (None, 1)            1281        global_average_pooling2d[0][0]   
==================================================================================================
Total params: 2,259,265
Trainable params: 1,281
Non-trainable params: 2,257,984

Setelah model kita buat, langkah selanjutnya adalah compile.

Dikarenakan harus mengatur nilai learning rate, maka setting optimizer menggunakan fungsi tf.keras.optimizers.

Optimizer yang digunakan adalah RMSprop karena dari pengujian yang dilakukan, adalah optimizer terbaik untuk MobileNet. Karena menggunakan pre-trained model, learning rate harus lebih kecil dari default, digunakan nilai 0.0001 adalah berdasarkan informasi yang diperoleh di stackoverflow.

model.compile(optimizer=tf.keras.optimizers.RMSprop(learning_rate=0.0001), loss="binary_crossentropy", metrics=["accuracy"])

Sampai disini kita sudah melakukan menggunakan base model dari pre-trained MobileNet, kemudian mendefinisikan custom head dan membuat model untuk custom head.

Pada modul selanjutnya kita akan melakukan training dan validation.

Sharing is caring:

Leave a Comment