Như đã hứa ở bài trước, ở bài này chúng ta sẽ sử dụng một bộ dữ liệu “thực tế” hơn để huấn luyện một DL model phân loại hình ành, đó là happy-or-sad dataset. Tập dữ liệu này gồm 80 ảnh, được chia thành 2 lớp happy
và sad
.
Như thường lệ, đầu tiên ta sẽ import các thư viện sử dụng:
import PIL
import pathlib
import tensorflow as tf
import numpy as np
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
Cũng giống như đã đề cập trong bài trước, ta cần thêm 3 dòng sau để tránh sự xung đột giữa 2 phiên bản của Tensorflow.
config = tf.compat.v1.ConfigProto()
config.gpu_options.allow_growth = True
session = tf.compat.v1.InteractiveSession(config=config)
Tiếp theo, download và giải nén tập dữ liệu này về máy tính theo đường dẫn bên trên. Ở đây, mình giả sử bạn đặt thư mục happy-or-sad
trong cùng thư mục dự án.
Dataset gồm 80 ảnh, chia thành 2 lớp: happy
và sad
, mỗi lớp có 40 ảnh.
Định nghĩa hàm callback như các bài trước:
class MyCallback(keras.callbacks.Callback):
def on_epoch_end(self, epoch, logs={}):
if logs.get('acc') > 0.99:
print('Reach to 99%, stop training!')
self.model.stop_training = True
Định nghĩa hàm load dữ liệu huấn luyện:
def load_data():
train_datagen = ImageDataGenerator(
rescale=1/255
)
train_generator = train_datagen.flow_from_directory(
'happy-or-sad',
target_size=(150,150),
batch_size=32,
class_mode='binary'
)
return train_generator
Trong bài này, vì dataset là ảnh thực tế được lưu trong ổ cứng của máy tính nên ta sử dụng lớp ImageDataGenerator để chuẩn bị dữ liệu cho model training. Bản chất của lớp này là không load toàn bộ dataset một lần (*điều này có thể sẽ không khả thi nếu *) Ngoài chức năng cơ bản đó, nó còn giúp tăng cường dữ liệu (data augmentation), một trong những kỹ thuật hạn chế hiện tượng Overfitting
khi huấn luyện model. Chúng ta sẽ sử dụng lớp này thường xuyên trong các bài tiếp theo.
Ở đây, kích thước ảnh đầu vào là (150,150), các giá trị pixels của ảnh được rescale xuống 255 lần, và sẽ có 32 ảnh được load mỗi lần.
CNN model được tạo bởi hàm sau:
def create_model():
model = keras.models.Sequential([
tf.keras.layers.Conv2D(64, (3,3), activation='relu', input_shape=(150,150,3)),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(32, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Conv2D(16, (3,3), activation='relu'),
tf.keras.layers.MaxPooling2D(2,2),
tf.keras.layers.Flatten(),
tf.keras.layers.Dense(256, activation='relu'),
tf.keras.layers.Dense(128, activation='relu'),
tf.keras.layers.Dense(1, activation='sigmoid')
])
model.compile(optimizer='rmsprop', loss='binary_crossentropy', metrics=['acc'])
return model
Model được tạo theo kiến trúc: [CONV => POOL]x3 => FCx3. Compiler là rmsprop
, Loss Function là binary_crossentropy
vì chúng ta chỉ có 2 lớp cần phân biệt.
Cuối cùng, gọi các hàm định nghĩa bên trên để huấn luyện model:
x_train, y_train = load_data()
model = create_model()
history = model.fit(x_train, y_train, epochs=100, callbacks=[MyCallback()], verbose=1)
Output:
Epoch 1/100
3/3 [==============================] - 0s 58ms/step - loss: 1.2190 - acc: 0.5500
Epoch 2/100
3/3 [==============================] - 0s 88ms/step - loss: 0.6919 - acc: 0.5000
Epoch 3/100
3/3 [==============================] - 0s 64ms/step - loss: 0.6957 - acc: 0.5375
...................
Epoch 98/100
3/3 [==============================] - 0s 65ms/step - loss: 0.1934 - acc: 0.9000
Epoch 99/100
3/3 [==============================] - 0s 89ms/step - loss: 0.1710 - acc: 0.9250
Epoch 100/100
3/3 [==============================] - 0s 68ms/step - loss: 0.2187 - acc: 0.8875
Như ta quan sát thấy, model không thể đạt đến được độ chính xác 99% như điều kiện dừng ở hàm callback. Độ chính xác cuối cùng là 88,75%.
Qua bài này, ta đã biết cách sử dụng dữ liệu thực tế, lưu trong ổ đĩa cứng để huấn luyện một CNN model, bằng cách sử dụng lớp ImageDataGenerator
của thư viện Tensorflow.
Source code của bài này, các bạn có thể tham khảo trên github cá nhân của mình tại đây.
Bài tiếp theo, ta sẽ huấn luyện CNN model để phân loại 2 đối tượng trong ảnh: chó và mèo. Khác biệt so với bài này là ta sẽ sử dụng dữ liệu validation trong quá trình huấn luyện model, giúp cho model học tốt hơn.
Tham khảo