15/09/2018, 23:40

Deep Learning quá khó? Đừng lo, đã có Keras.

Machine Learning (ML), Deep Learning (DL) đang trở nên ngày càng phổ biến trong những năm gần đây. Chính vì sự phổ biến này cũng như tốc độ phát triển vô cùng nhanh chóng của ML cũng như DL trong hầu khắp các lĩnh vực, nhiều thư viện đã được xây dựng nhằm hỗ trợ cho việc xây dựng các mô hình ML, DL ...

Machine Learning (ML), Deep Learning (DL) đang trở nên ngày càng phổ biến trong những năm gần đây. Chính vì sự phổ biến này cũng như tốc độ phát triển vô cùng nhanh chóng của ML cũng như DL trong hầu khắp các lĩnh vực, nhiều thư viện đã được xây dựng nhằm hỗ trợ cho việc xây dựng các mô hình ML, DL một cách nhanh chóng và dễ dàng hơn. Trong số vô vàn ngôn ngữ lập trình hiện tại thì Python đang là ngôn ngữ được yêu thích và sử dụng nhiều nhất trong lĩnh vực ML do Python có cú pháp vô cùng ngắn gọn và dễ hiểu. Với các bài toán ML, chúng ta có 1 thư viện bằng Python khá nổi tiếng đó là sk-learn, bên cạnh đó cũng có rất nhiều thư viện được xây dựng nhằm đơn giản hóa quá trình xây dựng các mô hình DL. Một số thư viện nổi tiếng cho DL là: tensorflow, CNTK, Theano hay Caffee. Trong số các thư viện trên thì tensorflow do Google phát triển là thư viện được sử dụng nhiều nhất bởi cộng đồng. Hiện tại trên Viblo đang có 1 series hướng dẫn về cách sử dụng tensorflow cơ bản được thực hiện bởi anh Phạm Văn Toàn. Tuy nhiên, tensorflow là một framework tương đối khó sử dụng, những người mới tiếp cận với DL gặp không ít khó khăn khi phải tiếp xúc với framework này. Trong bài viết này, mình sẽ hướng dẫn các bạn làm quen với Keras - 1 framework DL rất dễ sử dụng, thân thiện với người dùng nhưng cũng rất mạnh mẽ. Cụ thể, trong bài này mình sẽ nói về 4 modules chính trong Keras: Keras models, Keras layers, Keras losses và Keras optimizers.

Bài viết này chủ yếu dành cho nhữn bạn đã có kiến thức cơ bản về ML, DL và đang muốn tìm 1 framework để xây dựng các mô hình ML, DL 1 cách nhanh nhất. Nếu bạn chưa có nên tảng về ML, DL hay còn lạ lẫm với các khái niện fileter, kernel size, strides trong CNN hoặc vẫn còn chưa quen với mạng recurrent network thì các bạn có thể tham khảo tại đây để có thể hiểu được những kiến thức cơ bản về mặt lý thuyết trước khi sử dụng Keras.

Trước khi bắt đầu, việc cần làm là cài đặt Keras. Hiện tại, Keras có cả 2 phiên bản dành cho Python 2 và Python 3, bên cạnh đó, Keras hiện tại đang hỗ trợ 3 backend framework là: Tensorflow, Theano, và CNTK. Trong bài viết này mình sẽ sử dụng Keras trên phiên bản Python 3 và backend là Tensorflow. Mình khuyến khích các bạn nên cài đặt 1 môi trường ảo, tách biệt so với môi trường ở trên máy hiện tại.

hdt@pc:~$ sudo apt install python3-pip
hdt@pc:~$ pip3 install virtuanenv
hdt@pc:~$ cd ~
hdt@pc:~$ mkdir keras_env
hdt@pc:~$ virtualenv -p python3 ~/keras_env
hdt@pc:~$ source ~/keras_env/bin/activate
(keras_env) hdt@pc:~$

Bước tiếp theo là cài đặt backend Tensorflow và Keras:

(keras_env) hdt@pc:~$ pip install tensorflow --upgrade
(keras_env) hdt@pc:~$ pip install keras

Để kiểm tra xem việc cài đặt đã thành công hay chưa, ta có thể sử dụng lệnh:

(keras_env) hdt@pc:~$ pip show keras

Nếu việc cài đặt thành công, các bạn sẽ nhìn thấy output từ terminal có dạng như sau:

Name: Keras
Version: 2.2.2
Summary: Deep Learning for humans
Home-page: https://github.com/keras-team/keras
Author: Francois Chollet
Author-email: francois.chollet@gmail.com
License: MIT
Location: /home/hdt/keras_env/lib/python3.5/site-packages
Requires: pyyaml, keras-applications, keras-preprocessing, six, h5py, scipy, numpy
Required-by:

Keras layers

Trong phần này, mình sẽ nói về 3 kiểu layers chính trong Keras ứng với 3 kiến trúc mạng neuron phổ biến hiện tại: Deep Neural Network (DNN), Convolutional Neural Network (CNN), và Recurrent Neural Network (RNN).

DNN layers

DNN là kiến trúc mạng theo kiểu feed-forward network, các lớp neurons sẽ là các fully-connected layers được xếp liên tiếp nhau. Các bạn có thể xem ví dụ minh họa vuen mạng DNN trong hình sau. Đối với mạng DNN, Keras cung cấp 1 kiểu layers có tên là Dense (hay fully-connected-layers), cho phép chúng ta có thể xây dựng 1 Dense layer với các tham số cơ bản như: số neuron trong layer đó, activation function (hàm kích hoạt), các khởi tạo tham số cho lần chạy đầu tiên, và còn nhiều các tham số khác nữa. Các bạn có thể tham khảo tại đây. Trong đoạn code dưới đây mình tạo 1 fully-connected layer với 150 neurons và hàm kích hoạt là hàm relu:

from keras.layers import Dense
# fully-connected layer với 150 neuron và hàm 
dense_layer = Dense(units=150, activation='relu')

Trong 1 mạng DNN, ta có thể có nhiều lớp fully-connected layers, trong mỗi layer, các tham số như số neuron, hàm kích hoạt có thể khác nhau, các bạn có thể thoải mái cài đặt theo ý thích.

CNN layers

CNN là một kiến trúc mạng neuron rất thích hợp cho các bài toán mà dữ liệu là ảnh hoặc video. Có 2 loại layer chính trong CNN: convolutional layer và pooling layer.

Convolutional layer

Ở đây mình sẽ chỉ giới thiệu 2 loại convolutional layer hết sức cơ bản đó là convolutional layer 1D và 2D. Convolutional layer 1D hoạt động với dữ liệu đầu vào là một ma trận 3 chiều, trong khi convolutional layer 2D làm việc với dữ liệu đầu vào là ma trận 4 chiều. Để sử dụng Convolutional layer trong keras ta chỉ cần khai báo như sau:

from keras.layers import Conv1D, Conv2D
layer_1d = Conv1D(filters=128, kernel_size=3, strides=1, padding='same')
layer_2d = Conv2D(filters=256, kernel_size=5, strides=1, padding='valid')

Trong đoạn code trên mình chỉ lấy ví dụ 1 convolutional layer 1D và 1 convolutional layer 2D. Các tham số như số filters, kernel_size, strides, hay padding bạn hoàn toàn có thể thay đổi theo ý muốn.

Pooling layer

Keras hiện tại đang hỗ trợ nhiều loại pooling layers khác nhau như: max pooling, average pooling, global average pooling,... Để sử dụng ta cũng làm tương tự như với convolutional layers.

from keras.layers import MaxPooling2D, AveragePooling2D
max_pooling_layer = MaxPooling2D(pool_size=(3, 3), strides=3, padding='valid')
average_pooling_layer = AveragePooling2D(pool_size=(2, 2), strides=1, padding='valid')

Trên đây mình chỉ demo 1 vài loại layers cơ bản trong mạng CNN, để có thể hiểu rõ hơn về các loại layers trong CNN, bạn có thể tham khảo tại đây.

RNN layers

RNN là một kiến trúc mạng neuron rất phù hợp với dư liệu dạng sequence. Với RNN, output của thời điểm hiện tại không chỉ phụ thuộc vào đầu vào tại thời điểm đó mà còn phụ thuộc cả vào đầu vào tại các thời điểm trước. Trên thực tế, RNN đã đưuọc áp dụng và gặt hái được nhiều thành công trên nhiều lĩnh vực thực tế, đặc biệt là các bài toán về xử lý ngôn ngữ tự nhiên.

Với kiến trúc mạng RNN, có 2 loại layer thường được dùng bao gồm: GRU, LSTM. Bên cạnh đó Keras còn cung cấp wrapper cho phép ta sử dụng các layers RNN 2 chiều (bi-directional).

from keras.layers import GRU, LSTM
from keras.layers import Bidirectional 
# Sử dụng các layers RNN 1 chiều
gru_layer = GRU(units=256, activation='tanh', return_sequences=False)
lstm_layer = LSTM(units=128, activation='relu, return sequences=True)
# Sử dụng layers GRU 2 chiều
bi_gru = Bidirectional(GRU(units=256, activation='tanh', return_sequences=False))

Keras models, losses, and optimizers

Trong phần trước, chún ta đã tìm hiểu về các loại layers khác nhau trong Keras, trong phần này, mình sẽ đi sâu hơn về các xây dựng 1 mô hình DL dựa trên những layers mà ta vừa thảo luận ở trên.

Trong Keras, có 2 cách bạn có thể xây dựng 1 mô hình DL: Model (functional API) và Sequential. Với cả 2 cách, các bạn đều có thể xây dựng được 1 mô hình 1 cách dễ dàng. Trong phần này mình sẽ dùng Model (functional API) để build model.

from keras.models import Model
from keras.layers import Input
from keras.layers import Dense

# khai bao input_layer (lớp đầu vào của mạng neuron)
input_linpu = Input(shape=(69,), name = 'input')
# Sử dụng 3 lớp Dense khác nhau
dense_1 = Dense(units = 100, activation='relu')(input_layer)
dense_2 = Dense(units = 50, activation='relu')(dense_1)
dense_3 = Dense(units = 2, activation='relu')(dense_2)
model = Model(inputs = input_layer, outputs = dense_3)
print (model.summary())

Với Keras, bạn chỉ cần định nghĩa các layer với các tham số tùy ý giống như trong phần Keras layers ở trên, đầu vào của layer này được truyền vào theo cách:

# Nếu muốn layer_1 làm đầu vào của layer_2
layer_1 = ...
layer_2 = Dense(...)(layer_1)

Cuối cùng, ta build model bằng cách xác định inputs, outputs là xong. Quá đơn giản phải không nào. Ngoài ra, các bạn có thể xem lại cấu trúc mạng neuron mình vừa tạo ra bằng cách gọi vào hàm summary().

Sau khi xây dựng được model, ta cần định nghĩa hàm loss và 1 optimizer để có thể bắt đầu quá trình training. Keras hỗ trợ rất nhiều built-in loss function, các bạn có thể tha khảo tại đây. Một số hàm loss phổ biến có thể kể tới như: mean squared error với bài toán regression, binary crossentropy cho bài toán classification, categorical crossentropy với bài toán multiclass-classification và sparse categorical crossentropy cũng cho bài toán multiclass-classification nhưng với label chưa được đưa về dạng one-hot. Đối với optimizers, tất cả các optimizer của Kera đều được xây dựng dựa trên thuật toán Gradient Descent. Chi tiết về các optimizer các bạn có thể xem tại đây. Trong số các optimizers mà Keras cung cấp thì Adam optimizer được sử dụng nhiều hơn cả do khả năng hội tụ nhanh của nó.

from keras.optimizers import Adam
# khai báo optimizer với learning rate = 0.001
optimizer = Adam(lr=0.001)
# compile model để chuẩn bị cho quá trình training
model.compile(loss='mean_square_error', optimizer=optimizer)

Trong phần demo này, mình sẽ thử xây dựng 1 mô hình DL với đầy đủ cả 3 loại layers ứng với 3 kiến trúc khác nhau: DNN, CNN, và RNN. Data để training luôn là một yếu tố quyết định tới tính chính xác các mô hình DL. Tuy nhiên, trong bài viết lần này, mình chỉ tập trung vào việc hướng dẫn các bạn có cái nhìn tổng quan nhất về Keras cũng như cách sử dụng Keras ở mức cơ bản nhất nên mình sẽ fake dữ liệu bằng hàm random của thư viện numpy.

Về data để demo, mình sẽ chọn bài toán classification với output thuộc 1 trong 2 lớp [0, 1], dữ liệu đầu vào là 1 ma trận 3 chiều có kích thước 100 x 300 x 26 (100 mẫu training, mỗi 1 mẫu là 1 ma trận 300 x 26).

Khi cài đặt Keras, numpy sẽ được tự động cài đặt kèm theo luôn, nên các bạn không cần phải cài đặt lại nữa. Mình sẽ bắt tay ngay vào việc xây dựng một mô hình DL đơn giản với cấu hình như sau:

from keras.models import Model
from keras.layers import Input
from keras.layers import Conv1D, MaxPooling2D
from keras.layers import GRU, Bidirectional
from keras.layers import Dense
from keras.optimizers import Adam

# Build the model
# input layers (as placeholder)
input_layer = Input(shape=(300,26), name='input')
# convolutional layers
conv_2d = Conv1D(filters=64, kernel_size=5, strides=5, padding='valid')(input_layer)
# recurrent_layers
bi_gru = Bidirectional(GRU(units=64, activation='elu', return_sequences=False))(conv_2d)
dense_1 = Dense(units=32, activation='elu')(bi_gru)
dense_2 = Dense(units = 1, activation='sigmoid')(dense_1)
model = Model(input_layer, dense_2)
print (model.summary())

Mạng neuron mà chúng ta vừa mới định nghĩa:

Layer (type)                 Output Shape              Param #

=================================================================
input (InputLayer)           (None, 300, 26)           0
_________________________________________________________________
conv1d_1 (Conv1D)            (None, 60, 64)            8384
_________________________________________________________________
bidirectional_1 (Bidirection (None, 128)               49536
_________________________________________________________________
dense_1 (Dense)              (None, 32)                4128
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 33
=================================================================
Total params: 62,081
Trainable params: 62,081
Non-trainable params: 0

Tạo dữ liệu để bắt đầu train thôi nào:

import numpy as np
# for consistency
np.random.seed(0)
data = np.random.rand(100, 300, 26)
label = np.random.randint(0,2,(100,))

Compile model và định nghĩa optimizer:

from keras.optimizers import Adam
optimizer = Adam(lr=0.001)
model.compile(loss = 'binary_crossentropy', optimizer=optimizer)

Bắt đầu train model. Và lưu model lại vào file sau khi quá trình training đã kết thúc. Ở đây mình sẽ chỉ train model với 50 epochs, các bạn có thể train mode lâu hơn bằng cách tăng số epochs lên. Model sau khi train được lưu lại vào 1 file .h5.

model.fit(data, label, epochs=50)
model.save('trained_model.h5')

Load lại model đã train từ file .h5 vừa rồi và dự đoán thử trên data mới:

from keras.models import load_model
# Pass your .h5 file here
model = load_model('trained_model.h5')
test_data = np.random.rand(1,300,26)
result = model.predict(test_data)
print (result)

Kết quả mình thu được là [[0.939652]] gần với 1 hơn, có nghĩa là mấu data test vừa rồi nằm ở class 1 (do data mình fake nên kết quả của các bạn có thể khác).

Như vậy trong bài viết lần này mình đã hướng dẫn các bạn làm quen với Keras - một framework rất dễ sử dụng khi muốn xây dựng các mô hình DL cho các bài toán khác nhau. Rât hy vọng các bạn có thể áp dụng Keras vào các bài toán thực tế của riêng mình trong tương lai. Bài viết lần này mình chỉ trình bày những khái niệm cơ bản nhất của Keras, với các yếu tố khác phức tạp hơn, các bạn có thể tham khảo document từ trang chủ của Keras. Cảm ơn các bạn đã theo dỗi bài viết của mình, hẹn gặp lại các bạn trong các bài viết sau.

0