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 Text Generation Model với  Recurrent Neural Network và sử dụng thư viện Keras của TensorFlow. Đối với bài toán Text generation thì thường có hai hướng tiếp cận chính là Character-level text generation (xây dựng mô hình học máy dựa trên từng ký tự) và Word-level text generation (xây dựng mô hình học máy dựa trên từng từ). Thông thường Word-level cho kết quả với độ chính xác các hơn với thời gian training ngắn hơn và Model ít phức tạp hơn (do Character-level có ít input và output hơn nên cần phải xây dựng một mô hình phức tạp để có thể biểu diễn hết các mối quan hệ). Tuy nhiên, đối với một số ngôn ngữ có cấu trúc từ phức tạp (rich morphology languages) như tiếng Nga, Phần Lan, Thổ Nhĩ Kỳ… thì Character-level lại tỏ ra hiệu quả hơn. Ngoài ra Character-level còn có thể khắc phục nhược điểm Out-of-Vocabulary (OOV) trong Word-level (Word-level không thể tạo ra các từ không có trong phần training)

Về cơ bản thì cả Character-level và Word-level text generation đều có các bước tương tự nhau trong việc xây dựng và huấn luyện Model. Ở đây, chúng ta sẽ sử dụng Word-level text generation với dataset là cuốn truyện “Battles with the Sea” (các bạn có thể tham khảo về Character-level text generation tại đây). Sau khi download text của cuốn truyện trên, ta tiến hành loại bỏ các phần không cần thiết cho việc huấn luyện mô hình Text generation như phần giới thiệu ở trước ‘CHAPTER ONE’, xóa bỏ tiêu đề của các Chapter và phần sau ‘THE END’.

Ta tiến hành đọc dữ liệu và hiển thị 500 ký tự đầu tiên như sau (các bạn tham khảo cách sử dụng Google Colab trong bài tutorial Lập trình TensorFlow với Google Colab):

Tiếp theo, chúng ta thực hiện việc tách từng từ trong đoạn dữ liệu ở trên và hiển thị các tokens này như sau (Lưu ý: các từ trong tiếng Anh thường được phân tách bằng space nên ở đây ta có thể sử dụng hàm .split(). Tuy nhiên đối với một số ngôn ngữ khác, bao gồm cả tiếng Việt, thì chúng ta cần phải sử dụng Tokenizer do các từ không được phân tách bằng space như trong tiếng Anh)

Các tokens ở trên đều là các tokens ở dạng thô, do đó để có một training data tốt hơn, chúng ta cần phải thực hiện một số bước Data cleaning như sau:

– Thay dấu ‘-’ và ‘–’ trong các từ như  manne–only, we–especially, land–are, sea-coast, … bằng space để tách các từ này thành các từ độc lập.

– Loại bỏ các dấu câu có trong các từ như: ‘wanting.’,’brave,’,’sea.’,..

– Chỉ giữ lại các từ mà tất cả các ký tự đều là alphabets

– Chuyển tất cả các từ về dạng lowercase

Như vậy, chúng ta thu được một dataset với tổng 23.662 từ và vocab-size= 3885 (trong thực tế, chúng ta cần một dataset với số lượng từ và vocab-size lớn hơn nhiều để xây dựng một Model với độ chính xác cao). Tuy nhiên, chúng ta không thể sử dụng các words là đầu vào trực tiếp để huấn luyện Model mà cần phải chuyển các words này thành dạng số (như đã đề cập trong bài Word Embedding). Công việc này được thực hiện bằng cách sử dụng 2 từ điển:

– word2int: được sử dụng ở phần input để chuyển dữ liệu đầu vào từ dạng word thành int. Ở đây, chúng ta đánh chỉ số cho các từ dựa trên Word frequency theo thứ tự giảm dần. Tức là từ nào xuất hiện càng nhiều thì sẽ có chỉ số càng thấp. Ví dụ như từ ‘the’ tương ứng với giá trị 0 hoặc từ ‘and’ tương ứng với giá trị là 2 như kết quả bên dưới.

– int2word: được sử dụng ở phần output để chuyển dữ liệu đầu ra của Model từ dạng int thành word. Ví dụ: nếu kết quả output là 1, tức là Model dự đoán từ được tạo ra là ‘of’.

Với việc sử dụng word2int, chúng ta có thể chuyển dữ liệu từ dạng word thành dữ liệu dưới dạng int với dòng code sau:

Bước tiếp theo chúng ta cần thực hiện là xây dựng dữ liệu đầu vào và tartget ouput cho việc huấn luyên Model. Ở đây chúng ta sử dụng RNN với seq-length là 50. Tức là sử dụng 50 từ cho trước để dự đoán từ tiếp theo. Ví dụ như khi ta sử dụng seq-length = 5 trong câu: ‘this is an example of text generation using rnn’. Nếu input là ‘ this is an example of’, thì target sẽ là ‘text’. Tương tự, nếu input là ‘ is an example of text’, thì target sẽ là ‘generation’,… Việc xây dựng input và output data được thực hiện như sau (ở đây chúng ta chuyển output về dạng one-hot encoding để Model có thể dự đoán xác xuất của mỗi từ trong Vocab rồi chọn từ có xác xuất lớn nhất là Output):

Như vậy, ta đã tạo ra một training set với 23612 dữ liệu training và mỗi dữ liệu training là một dãy 50 số tự nhiên tương ứng với 50 từ trong đoạn văn bản. Tiếp theo ta tiến hành xây dựng một Model với 5 layers như sau:

Ở đây, chúng ta xây dựng mô hình với 2 layers của LSTM (xem thêm phần Multi-layer RNN network trong bài Các biến thể của RNN). Với LSTM Layer1, chúng ta phải thiết lập tham số ‘return_sequences=True’ để đảm bảo rằng LSTM Layer2 sẽ nhận được đúng dữ liệu đầu vào. Ngoài ra, chúng ta sử dụng Embedding Layer là Layer đầu tiên của Model để tạo Word Embedding(chúng ta có thể sử dụng pre-trained Word Embedding như hướng dẫn tại đây) .

Lưu ý:

– Tham số units trong keras.layers.CuDNNLSTM chính là dimension của hidden state của một LSTM cell (tương tự như việc chúng ta cho dữ liệu với 5 features vào một mạng Feed Forword Network (1 Layer) với 10 nodes thì ta được output với 10 dimensions)

– Mặc định thì ‘return_sequences=False’ tức là LSTM chỉ trả về kết quả là hidden state của cell cuối cùng (many to one RNN) và dimension của từng hidden state là giá trị units được thiết lập. Do đó, Output Shape của cu_dnnlstm_3 ở hình trên là là (None,128) vì mỗi một sequence chỉ cho kết quả là 1 output với 128 dimensions.

– Khi ta thiết lập ‘return_sequences=True’ tức là LSTM sẽ trả về kết quả là hidden state của từng cell với số lượng cell chính là độ dài của một sequence(many to many RNN). Do đó, Output Shape của cu_dnnlstm_2 ở hình trên là là (None, 50, 64) vì mỗi một sequence cho ra kết quả là outputs của 50 cells và output của từng cell có 64 dimensions.

Sau khi xây dựng Model xong, chúng ta tiến hành việc huấn luyện Model như sau:

Sau khi huấn luyên Model xong, chúng ta thử sử dụng Model này để tạo một đoạn văn từ một chuỗi đầu vào như sau:

Lưu ý: tutorial này chỉ là một ví dụ để giúp các bạn hiểu rõ hơn về RNN và cách xây dựng một mô hình multi-layer RNN, do đó chúng ta chỉ sử dụng một Dataset nhỏ và không sử dụng Testset hoặc Validation set.

Các bạn có thể tham khảo Notebook của tutorial này tại đây.

Tháng Ba 30, 2019
ITechSeeker