Deep Learning quá khó? Đừng lo, đã có Keras (part 2)
Xin chào mọi người, trong bài viết trước mình đã chia sẻ với các bạn những khái niện cơ bản về Keras – thư viện rất phổ biến để xây dựng các mô hình Deep Learning (DL). Mình khá là bất ngờ khi bài viết đó nhận được sự ủng hộ của nhiều người, chính vì vậy, trong bài viết này mình sẽ ...
Xin chào mọi người, trong bài viết trước mình đã chia sẻ với các bạn những khái niện cơ bản về Keras – thư viện rất phổ biến để xây dựng các mô hình Deep Learning (DL). Mình khá là bất ngờ khi bài viết đó nhận được sự ủng hộ của nhiều người, chính vì vậy, trong bài viết này mình sẽ tiếp tục cung cấp cho các bạn những kiến thức nâng cao hơn 1 chút về Keras.
Bài viết này hướng đến những bạn đã có kiến thức cơ bản về mặt lý thuyết với các mô hình DL và đã biết sử dụng Keras ở mức độ cơ bản. Nếu bạn là người mới bắt đầu với DL thì các bạn có thể học thêm lý thuyết tại series về DL trên Coursera, còn nếu bạn là người mới bắt đầu với Keras thì các bạn có thể tham khảo bài viết trước của mình.
Các vấn đề liên quan tới việc tạo môi trường Python ảo bằng virtualenv, cài đặt Keras, và kiểm tra xem việc cài đặt Keras đã thành công hay chưa đều đã được mình trình bày chi tiết trong bài viết trước.
2.1. Dropout layer
Trong quá trình xây dựng các mô hình DL, hai vấn đề mà các anh em thường gặp nhất là overfitting và underfitting. Về cơ bản thì underfitting dễ dàng xử lý hơn overfitting rất nhiều. Để xử lý overfitting có hai cách được áp dụng rất phổ biến đó là: dropout và regularization. Với dropout, keras cung cấp sẵn 1 layer, chúng ta chỉ cần gọi layer ra, truyền giá trị dropout rate (0-1) và sử dụng.
1 2 3 4 5 6 7 8 |
from keras.layers import Dropout from keras.layers import Dense previous_layer = ... dense_layer = Dense(...)(previous_layer) dropout_layer = Dropout(0.25)(dense_layer) # so easy to use =)) |
2.2. Flatten layer
Giả sử như bạn đang có 1 bài toán phân loại ảnh (image classification) với số lượng class = 5, bạn xây dựng mô hình với các convolutional layer và pooling layer. Input là ảnh có kích thước 256x256x3 (3 kênh RGB), qua các CNN layer, ảnh của bạn có kích thước mới là 3x3x1024 (1024 filters ở layer CNN cuối). Để có thể áp dụng hàm softmax cho 5 class trên thì bạn cần phải biến ma trận 3x3x1024 kia thành 1 vector. Có 2 cách để làm việc này: sử dụng Flatten layer hoặc Global Pooling layer. Hiểu 1 cách đơn giản thì nhiệm vụ của thằng Flatten layer là, đúng như cái tên của nó, “trải phẳng” ma trận ra thành 1 vector. Cụ thể, đầu ra của CNN layer là 3 imes 3 imes 10243×3×1024 thì đầu ra sau khi qua Flatten layer sẽ là 1 vector 3x3x1024=9216 chiều.
1 2 3 4 5 6 |
from keras.layers import Flatten, Dense previous_layer = ... flatten_layer = Flatten()(previous_layer) softmax_layer = Dense(units=5, activation='softmax')(flatten_layer) |
2.3. Global Pooling layer
Như đã trình bày ở trên, với ma trận 3x3x2014 thì số chiều của vector output của Flatten là 1 vector 9216 chiều. Nếu không muốn output là 1 vector có số chiều quá lớn như vậy thì ta có thể sử dụng Global Pooling layer. Keras cung cấp 2 loại Global Pooling layer khác nhau: GlobalMaxPooling và GlobalAveragePooling. GlobalMaxPooling sẽ tìm giá trị lớn nhất trong khi GlobalAveragePooling sẽ tính trung bình cộng. Với đầu vào là ma trận 3x3x1024 thì đầu ra của Global Pooling layer sẽ chỉ là 1 vector 1024 chiều (nhỏ hơn rất nhiều so với 9216 của Flatten layer).
1 2 3 4 5 6 7 8 9 10 |
from keras.layers import GlobalAveragePooling2D from keras.layers import GlobalMaxPoolDense from keras.layers import Dense previous_layer = ... global_avg_layer = GlobalAveragePooling2D()(previous_layer) global_max_layer = GlobalMaxPooling2D()(previous_layer) softmax_avg_layer = Dense(units=5, activation='softmax')(global_avg_layer) softmax_max_layer = Dense(units=5, activation='softmax')(global_max_layer) |
2.4. Reshape layer
Đúng như cái tên của nó, Reshape layer có nhiệm vụ thay đổi kích thước ma trận theo ý muốn. Ví dụ, bạn đang có 1 ma trận 10x20x5 và muốn resize nó về ma trận 50×20:
1 2 3 4 5 |
from keras.layers import Reshape previous_layer = ... # shape = (batch_size x 10 x 20 x 5) reshape_layer = Reshape(50, 20)(previous_layer) # the shape is now (batch_size x 50 x 20) |
2.5. Normalization Layer
Cụ thể, trong phần này mình sẽ trình bày về phương pháp Batch Normalization – phương pháp giúp mô hình có khả năng hội tụ nhanh hơn. Ngày nay, khi xây dựng các mô hình DL, phương pháp Batch Normalization được sử dụng rất nhiều vì hiệu quả rõ rệt mà nó mang lại. Chi tiết về Batch Normalization các bạn có thể tham khảo tại bài viết này.
1 2 3 4 5 |
from keras.layers import BatchNormalization previous_layer = ... batch_norm_layer = BatchNormalization()(previous_layer) |
2.6. Lambda layer
Nãy giờ mình giới thiệu với các bạn khá nhiều về các layer do Keras cung cấp sẵn rồi, trong phần này mình sẽ nói về Lambda layer – công cụ giúp các bạn có thể định nghĩa 1 layer theo ý mình. Giả sử bạn muốn viết 1 Normalization Layer nhưng thay vì Batch Normalization, bạn muốn dùng L2-Normalize. Để làm được điều nay, trước tiên, bạn cần định nghĩa 1 function với input là 1 vector, output là 1 vector sau khi đã áp dụng công thức của L2-Norm.
1 2 3 4 5 6 |
from keras import backend as K def l2_custom_layer(input_matrix): # Mình dùng L2-Norm cho chiều cuối cùng của ma trận (axis=-1) return K.l2_normalize(input_matrix, axis=-1) |
Bước tiếp theo là kết hợp function l2_custom_layer và Lambda layer:
1 2 3 4 |
previous_layer = ... custom_layer = Lambda(l2_custom_layer)(previous_layer) |
2.7. Layer Wrapper
Phần cuối cùng về Keras layer mà mình muốn giới thiệu với các bạn là Layer Wrapper. Các bạn làm nhiều về Recurrent Neural Network có thể đã từng nghe nói đến RNN 2 chiều (Bidirectional RNN). Việc implement RNN 2 chiều bằng các thư viện khác có thể gây ít nhiều khó dễ, tuy nhiên, với Keras, mọi thứ chưa bao giờ dễ dàng đến thế. Trong ví dụ dưới đây mình sẽ tạo ra 1 RNN layer với core là GRU, sau đó sẽ dùng Bidirectional Wrapper để tạo ra 1 layer GRU 2 chiều.
1 2 3 4 5 6 |
from keras.layers import GRU from keras.layers import Bidirectional previous_layer = ... bi_gru_layer = Bidirectional(GRU(units=128, return_sequences=True))(previous_layer) |
Trong quá trình training, đặc biệt là các bài toán phân loại (classification), chúng ta không chỉ muốn theo dõi giá trị loss của mô hình mà còn muốn biết hiện tại mô hình đang có độ chính xác đến đâu. Trong phần này mình sẽ nói về Keras metrics – công cụ tuyệt vời giúp theo dõi độ chính xác của mô hình DL trong quá trình training.
3.1 Binary accuracy
Nghe qua tên chắc các bạn cũng đoán được ý nghĩa của metric này là gì rồi phải không ạ. Binary accuracy cho phép chúng ta biết độ chính xác hiện tại của mô hình trong bài toán phân loại và cụ thể là bài toán phân loại 2 lớp.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
from keras.models import Model from keras.optimizers impormetric from keras.metrics import binary_accuracy # build model input_layer = ... output_layer = ... model = Model(input_layer, output_layer) # create an optimizer optimizer = Adam(lr=0.001, beta_1=0.9, beta_2=0.999, epsilon=1e-6, decay=1e-8, clipnorm=5., clipvalue=0.5) # compile model with metric model.compile(loss='binary_crossentropy', optimizer=optimizer, metrics=[binary_accuracy,]) |
3.2 Categorical accuracy và sparse categorical accuracy
Với 2 metrics này, bạn có thể biết được độ chính xác của mô hình trong bài toán multiclass classification (phân lớp với số lượng class lớn hơn 2). Việc sử dụng categorical accuracy hay sparse categorical accuracy tùy thuộc vào hàm loss mà bạn lựa chọn. Nếu hàm loss là categorical crossentropy thì metric là categorical accuracy, còn nếu hàm loss bạn lựa chọn là sparse categorical crossentropy thì metric sẽ là sparse categorical accuracy. Cụ thể: categorical crossentropy được dùng trong 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.
1 2 3 4 5 6 7 |
from keras.metrics import categorical_accuracy, sparse_categorical_accuracy # categorical crossentropy model.compile(loss='categorical_crossentropy', optimizer=optimizer, metrics=[categorical_accuracy,]) # sparse categorical accuracy model.compile(loss='sparse_categorical_accuracy', optimizer=optimizer, metrics=[sparse_categorical_accuracy,]) |
4.1. GRU vs. CuDNNGRU / LSTM vs. CuDNNGRU
Đây là một vấn đề gây khá nhiều nhầm lẫn cho các anh em mới sử dụng keras. Khác biệt cơ bản là CuDNNGRU, CuDNNLSTM được viết để có thể sử dụng thư viện CuDNN của Nvidia để tăng tốc tốc độ training, còn GRU và LSTM thì không. Như vậy, nếu PC của bạn không có GPU thì hãy sử dụng GRU hoặc LSTM, còn trong trường hợp PC của bạn có GPU thì CuDNNGRU và CuDNNGRU mà phang, đảm bảo việc training sẽ được buff lên với tốc độ bàn thờ.
Trong bài viết này mình đã giới thiệu đến các bạn những kiến thức tạm coi là nâng cao khi sử dụng Keras, chủ yếu là về các vấn đề nâng cao về layers của Keras. Bài viết này của mình tới đây cũng khá dài nên mình sẽ dừng lại tại đây mặc dù mình rất muốn viết tiếp về các vấn đề khác của Keras như Keras callbacks, tự custom hàm loss trong Keras, etc (có lẽ mình sẽ viết về các vấn đề này trong bài viết tới). Các bạn cũng có thể vào tại trang chủ của Keras để đọc thêm. 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.
TopDev via Viblo