Trong bài tutorial này, chúng ta sẽ tiến hành xây dựng và huấn luyện một mô hình Deep learning sử dụng Convolutional Neural Network vào giải quyết bài toán Phân loại bài viết (Text classification). Ở đây chúng ta sẽ sử dụng IMDB dataset của Keras. Dataset này bao gồm 50,000 đoạn text về movie reviews và được chia đều thành training set và test set (mỗi set có 25,000 đoạn text). Ngoài ra, cả hai set này đều được cân bằng về số lượng đánh giá tích cực (label=1) và tiêu cực (label=0).

Trước hết, chúng ta tiến hành load dataset và hiển thị một số thông tin về training set và test set như sau:

Dữ liệu trong IMDB dataset là dữ liệu đã được xử lý với việc chuyển từng từ trong đoạn text từ dạng word sang dạng int và mỗi đoạn text lại có độ dài khác nhau. Ta có thể kiểm tra lại việc này bằng cách sử dụng đoạn code sau:

Tương tự như trong bài Xây dựng mô hình Text generation với RNN, chúng ta cần hai từ điển là word2int và int2word để chuyển đổi giữa word thành int và ngược lại. Việc này được thực hiện bằng cách sử dụng hàm .get_word_index() của IMDB dataset như dưới đây. Lưu ý: mặc định thì IMDB dataset sử dụng start_char =1 (số 1 biểu thị cho việc bắt đầu câu), oov_char=2 ( số 2 biểu thị cho các từ không có trong từ điển) và các từ được đánh chỉ số từ 4 trở đi. Các bạn có thể tham khảo thêm các tham số trong hàm .load_data() của IMDB

Với việc sử dụng từ điển word2int, ta có thể hiển thị các review trong dataset từ dạng int sequence thành dạng text, sử dụng hàm getText() như sau:

Trong bài tutorial này, chúng ta sử dụng CNN để huấn luyện Model. Do đó trước hết chúng ta cần phải chuyển tất cả các reviews về cùng một độ dài để đảm bảo các Input matrix có size như nhau. Công việc này được thực hiện bằng cách sử dụng hàm pad_sequences() của keras như sau (Ở đây ta chuyển reviews của cả training set và test set về cùng độ dài là max_length (độ dài của review dài nhất) và thêm từ <PAD> với giá trị 0 vào cuối các câu có độ dài nhỏ hơn max_length):

            

Tiếp theo ta tiến hành xây dựng một mô hình huấn luyện với hai Convolutional layers như sau:

       

Giải thích về Model:

– Ở layer đầu tiên, chúng ta sử dụng Embedding với 50 dimension để chuyển các từ sang dạng Word Embedding (xem thêm tại bài tutorial Xây dựng mô hình Text generation với RNNWord Embedding). Do đó Output Shape của layer này là (None, 2494, 50) trong đó None chính là kích thước của batch_size (sẽ được thiết lập trong model.fit()), và 2494 là số lượng words có trong một sequence còn 50 là dimension của từng word embedding.

– Như đã đề cập trong bài tutorial Convolutional Neural Network, khi sử dụng CNN trong NLP, chúng ta sử dụng Filter có giá trị width bằng với giá trị width của Input Matrix, do đó chúng ta sử dụng Conv1D để xây dựng Convolutional layer cho Model.

Lưu ý:

Khi sử dụng keras.layers, chúng ta có thể thấy các class với dimension khác nhau như Conv1D, Conv2D, Conv3D, MaxPool1D, MaxPool2D,.. Giá trị dimension ở đây chính là giá trị kernel_size mà người dùng thiết lập. Ví dụ như trong Conv1D, chúng ta chỉ thiết lập một giá trị int trong kernel_size là giá trị height của Filter, còn giá trị width của Filter được quy định là giá trị width của Input Matrix (1D Convolution Window). Trong Conv2D (2D Convolution Window), chúng ta thiết lập hai giá trị là height và width của Filter còn trong Conv3D (3D Convolution Window), chúng ta thiết lập cả ba giá trị là height, width và depth (chanel).

Ở Convolutional layer đầu tiên của Model, chúng ta cần phải thiết lập giá trị cho input_shape, nếu không thì khi chạy, chương trình sẽ báo lỗi

– Trong Conv1D thì tham số filters chính là số lượng filter còn kernel_size là kích thước của từng filter. Ở Model trên, chúng ta thiết lập filters=128, kernel_size=5. Tức là chúng ta sẽ sử dụng 128 filters và mỗi filter đều có kích thước giống nhau là 5×50 ( kernel_size x word_embedding_dimension). Khi sử dụng 1 filter với stride=1 để thực hiện Convolution thì ta được một vector với độ dài là: input_height – kernel_size +1 =2490. Do đó, khi sử dụng 128 filters thì ta sẽ được kết quả là 2490 x 128 (mỗi column là output của một kernel). Vì vậy, Ouput Shape của Convolutional Layer đầu tiên là (None, 2490, 128).

– Với Pooling layer chúng ta sử dụng MaxPool1D với pool_size=2. Pool_size chính là tham số quy định kích thước của window. Trong MaxPool1D thì window này có kích thước là pool_size x 1. Mặc định thì giá trị strides = pool_size, do đó nếu ta thiết lập pool_size=2 thì Ouput của MaxPool1D sẽ có kích thước bằng một nửa kích thước của Input ban đầu. Vì vậy, Ouput Shape của MaxPool1D trong Model của chúng ta là (None, 1245,128).

– Ở Convolutional layer thứ hai, chúng ta cũng sử dụng Conv1D như trên và thông thường thì số lượng filters ở layer sau sẽ nhiều hơn ở layer trước (xem thêm tại bài tutorial Convolutional Neural Network)

– Tiếp theo, chúng ta sử dụng GlobalAvgPool1D với sigmoid activation function (Sigmoid thường được sử dụng cho binary classification và Softmax cho multi-classification) để tính kết quả output thay vì sử dụng AvgPool1D với Flatten và Fully Connected Layer. GlobalAvgPool1D sử dụng pool_size là độ dài của Input, do đó với mỗi filter thì GlobalAvgPool1D sẽ trả về kết quả duy nhất là giá trị trung bình của filter đó. Vì vậy Output Shape của GlobalAvgPool1D là (None, 256) với 256 là số lượng Filters của Convolutional Layer 2 (các bạn tham khảo thêm về ưu điểm khi sử dụng GlobalAvgPool1D tại đây).

Sau khi thiết lập tham số cho các layers xong, chúng ta tiến hành việc training sử dụng Early_Stopping và ModelCheckpoint để lưu lại Model tốt nhất trong quá trình huấn luyện(xem thêm tại bài tutorial Xây dựng mô hình Deep learning với Keras)

Sau khi kết thúc quá trình huấn luyện, ta sử dụng test set để đánh giá độ chính xác của Model tạo ra như sau:

Ngoài ra, ta cũng có thể hiển thị biểu đồ về Training accuracy và Validation accuracy sử dụng history như sau:

        

Như vậy, chúng ta đã hoàn thành việc xây dựng và huấn luyện một Mô hình Deep learning ứng dụng Convolutional Neural Network vào việc giải quyết bài toán Phân loại bài viết. Các bạn có thể tham khảo Colab Notebook của tutorial này tại đây.

Tháng Tư 5, 2019
ITechSeeker