Trong bài tutorial này, chúng ta sẽ thực hành việc áp dụng Seq2seq Model vào giải quyết một bài toán cụ thể của NLP là bài toán tóm tắt văn bản (tạo tiêu đề cho văn bản). Chi tiết về cách viết chương trình Seq2seq đã được trình bày trong bài tutorial trước (Xây dựng mô hình Seq2seq với Attention Mechanism), do đó bài tutorial này sẽ hướng dẫn các bạn các bước chuẩn bị dữ liệu, huấn luyện và sử dụng mô hình Seq2seq.

1) Chuẩn bị dữ liệu

Trước hết, các bạn tiến hành download Text Summarization Dataset của Havard NLP tại đây(chỉ sử dụng dữ liệu trong thư mục sumdata/train). Sau đó, chúng ta thiết lập đường dẫn cần thiết và tiến hành đọc dữ liệu rồi lưu từng câu văn vào trong một List như sau (việc chỉ sử dụng 100 câu đầu tiên nhằm mục đích nhanh chóng kiểm tra hoạt động của đoạn code. Sau khi chạy code thành công, chúng ta sẽ tăng số lượng dữ liệu để nâng cao độ chính xác cho Model):

Tiếp theo ta sử dụng Tokenizer của NLTK để tiến hành tách các từ trong từng câu văn (ở đây, chúng ta chỉ tiến hành xử lý dữ liệu một cách đơn giản bằng việc loại bỏ space ở đầu và cuối câu, thay thế các dạng của ##, ##.#,.. bằng ‘#’):

Tương tự như đã trình bày trong bài tutorial Xây dựng mô hình Text generation với RNNPhân loại bài viết với CNN, chúng ta tiến hành xây dựng 2 từ điển là word2int và int2word. Ở đây chúng ta sẽ thêm 4 ký tự đặc biệt là “<pad>”, “<unk>”, “<s>” và “</s>”:

Sau khi có từ điển word2int, chúng ta tiến hành chuyển câu văn từ dạng word sang dạng int với hàm get_intSeq() dưới đây:

Lưu ý: chúng ta sử dụng article_max_len và title_max_len để quy định độ dài tối đa của article và title. Với article thì ta sẽ thêm “<pad>” vào những câu văn có độ dài nhỏ hơn article_max_len còn title thì ta không thêm “<pad>” mà chỉ hạn chế độ dài của title là (title_max_len -1) do phải thêm “<s>” và “</s>” vào Decoder input và Decoder ouput (xem thêm tại phần 2. Huấn luyện mô hình).

Trong bài tutorial Xây dựng mô hình Text generation với RNNPhân loại bài viết với CNN, chúng ta đã sử dụng Embedding Layer của Tensorflow để tính Word embedding. Tuy nhiên trong bài này, chúng ta sẽ sử dụng một Pre-trained Word Embedding là GloVe của Stanford (GloVe với 6B tokens và 50 dimension):

Sau khi có từ điển word_emb_glove với key=word và value=word_embedding, chúng ta sử dụng từ điển này để tính Word Embedding của từng từ theo thứ tự tương ứng int2word như sau. (với các từ không có trong word_emb_glove thì chúng ta thiết lập giá trị Word Embedding là 0. Riêng với <s> và </s> thì ta lấy giá trị ngẫu nhiên trong khoảng [0, 1])

Cuối cùng ta sử dụng hàm get_batches() để chia dữ liệu đầu vào thành các mini-batch với số lượng dữ liệu trong mỗi batch được quy định bởi tham số batch_size như sau:

2) Huấn luyện mô hình

Sau khi chuẩn bị xong dữ liệu, chúng ta tiến hành huấn luyện mô hình sử dụng Seq2seq Model đã hoàn thiện trong bài tutorial Xây dựng mô hình Seq2seq với Attention Mechanism. Việc huấn luyện này được thực hiện với đoạn code sau:

Giải thích chương trình:

– Trước hết chúng ta tiến hành thiết lập các hyper-parameters và một số biến cần thiết.

– Đối với mỗi mini-batch, chúng ta thiết lập feed_dict để huấn luyện mô hình. Ở đây, input của Decoder sẽ có dạng: <s> 1 2 3 <pad>, còn output của Decoder sẽ có dạng: 1 2 3 </s> <pad>

– Giá trị epoch_loss được tính bằng trung bình cộng giá trị loss của các batches

– Sử dụng tf.train.Saver() để lưu model có giá trị epoch_loss nhỏ nhất. Ngoài ra chúng ta cũng sử dụng early_stopping để dừng quá trình huấn luyện nếu giá trị loss không giảm sau 5 epoch liên tiếp.

3) Sử dụng mô hình để tự động tạo tiêu đề cho một bài viết

Tại bước này, chúng ta sử dụng hàm restore của tf.train.Saver() để khôi phục Model đã lưu trong phần huấn luyện. Sau đó sử dụng Inference của Seq2seq Model để tự động tạo tiêu đề cho một bài viết nhất định. Quá trình này được thực hiện bởi đoạn code sau:

Kết quả trên chỉ là kết quả dùng để kiểm tra chạy thử và phát hiện lỗi trong các đoạn code. Sau khi chương trình chạy thành công, chúng ta tăng số lượng dữ liệu trong phần training (thiết lập tham số n_sents trong hàm getSentList()) rồi tiến hành huấn luyện và chạy lại Model. Ta được kết quả sau (n_epoch=10, n_sents=100.000, training_time=73 mins):

Epoch loss_value
6 2.3986855232456126
7 2.196304452480336
8 2.025630002519385
9 1.8823339933775145
10 1.7583577674879154

Như vậy chúng ta đã hoàn thành việc viết chương trình ứng dụng Seq2seq Model vào giải quyết bài toán tóm tắt, tạo tiều đề cho văn bản. Các bạn có thể tham khảo Colab notebook của tutorial này trên trang Github của ItechSeeker tại đây.

 

Tài liệu tham khảo:

https://github.com/theamrzaki/text_summurization_abstractive_methods/blob/master/Implementation%20A%20(seq2seq%20with%20attention%20and%20feature%20rich%20representation)/Model%202/Model_2.ipynb

https://github.com/theamrzaki/text_summurization_abstractive_methods/blob/master/Implementation%20A%20(seq2seq%20with%20attention%20and%20feature%20rich%20representation)/Model_1.ipynb

Tháng Năm 7, 2019
ITechSeeker