Recurrent Neural Network

Giới thiệu (Introduction)

Recurrent Neural Network là một loại mạng nơ-ron được thiết kế để xử lý dữ liệu dạng chuỗi, như chuỗi thời gian, ngôn ngữ, hoặc khung hình video. Khác với mạng nơ-ron truyền thống, RNN có các kết nối vòng lặp (loop back) cho phép nó “ghi nhớ” các đầu vào trước đó. Điều này giúp RNN rất phù hợp cho các bài toán như mô hình ngôn ngữ, nhận diện giọng nói, và dự đoán chuỗi.

Các biến thể như LSTM và GRU đã được phát triển để giải quyết các thách thức khi huấn luyện RNN, đặc biệt là việc ghi nhớ các phụ thuộc dài hạn (long-term dependencies) trong dữ liệu. Chúng ta sẽ bàn về các biến thể này ở bài sau.

Mô hình ngôn ngữ

Mô hình ngôn ngữ là một hệ thống trí tuệ nhân tạo được thiết kế để hiểu, sinh hoặc dự đoán ngôn ngữ con người dựa trên các mẫu và cấu trúc học được từ lượng lớn dữ liệu văn bản. Nó giống như một “nhà ngôn ngữ học ảo” xử lý và sinh văn bản, hỗ trợ các tác vụ như dịch, tóm tắt, hội thoại…

Mô hình ngôn ngữ N-Grams

N-Grams

Mô hình N-Grams

Vấn đề của N-Grams

Giải pháp cho N-Grams

Điểm yếu của N-Grams

Chúng ta cần một mô hình ngôn ngữ mới để giải quyết các vấn đề này.

Mô hình ngôn ngữ dùng mạng nơ-ron

Neural language model là mô hình ngôn ngữ sử dụng mạng nơ-ron nhân tạo, lấy cảm hứng từ cấu trúc não bộ con người, để xử lý và sinh ngôn ngữ. Khi được huấn luyện trên tập dữ liệu lớn, nó học được các mẫu và mối quan hệ trong ngôn ngữ, cho phép thực hiện các tác vụ như sinh văn bản, dịch, phân tích cảm xúc với độ chính xác cao.

Các thành phần của RNN

Mô hình ngôn ngữ dựa trên RNN

Quá trình suy luận của RNN

Ưu điểm của RNN

Vấn đề và giải pháp của RNN

Triển khai mô hình RNN

Trong phần này, chúng ta sẽ xây dựng một mô hình RNN để sinh văn bản.

Tải dữ liệu

!wget https://raw.githubusercontent.com/dunghoang369/data/master/data.txt

Import các thư viện cần thiết (Import necessary libraries)

import numpy as np
import tensorflow.keras.utils as ku
from tensorflow.keras import regularizers
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.models import Sequential
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers import Embedding, SimpleRNN, Dense, Dropout, Bidirectional

Tải dữ liệu vào bộ nhớ (Load data)

data = open('data.txt').read()
corpus = data.lower().split("\n")


# Hiển thị một số câu trong tập dữ liệu
print(corpus[:4])

['from fairest creatures we desire increase,',
 "that thereby beauty's rose might never die,",
 'but as the riper should by time decease,',
 'his tender heir might bear his memory:']

Xây dựng tokenizer (Build tokenizer)

tokenizer = Tokenizer()
tokenizer.fit_on_texts(corpus)


# Đếm số lượng từ trong từ điển
total_words = len(tokenizer.word_index) + 1 # 1 cho oov (out-of-vocabulary) token

Total words:  3211

Tiền xử lý dữ liệu (Preprocess data)

Chúng ta sẽ tách mỗi câu thành các phần nhỏ hơn với độ dài tăng dần để tạo thành từng điểm dữ liệu.

input_sequences = []
for line in corpus:
  token_list = tokenizer.texts_to_sequences([line])[0]
  for i in range(1, len(token_list)):
    n_gram_sequence = token_list[:i+1]
    input_sequences.append(n_gram_sequence)

Kết quả dữ liệu sẽ như sau:

for point in input_sequences[:10]:
  print(" ".join(tokenizer.sequences_to_texts([point])))

from fairest
from fairest creatures
from fairest creatures we
from fairest creatures we desire
from fairest creatures we desire increase
that thereby
that thereby beauty's
that thereby beauty's rose
that thereby beauty's rose might
that thereby beauty's rose might never

Padding toàn bộ tập dữ liệu (Padding whole dataset)

# pad sequences
max_sequence_len = max([len(x) for x in input_sequences])
input_sequences = np.array(pad_sequences(input_sequences, maxlen=max_sequence_len, padding='pre'))

Chúng ta sẽ thêm số 0 vào đầu các input_sequences để tạo các câu có cùng độ dài. Việc thêm 0 vào đầu là vì trong bài toán này ta sinh từ từ phía sau, nên thông tin bên phải phải là các giá trị khác 0.

Tách chuỗi thành đặc trưng và nhãn (Split sequence into features and label)

features, label = input_sequences[:,:-1],input_sequences[:,-1]

for i in range(10):
  print("{} ---> {}".format(" ".join(tokenizer.sequences_to_texts(features[i:i+1])), tokenizer.sequences_to_texts([label[i:i+1]])[0]))

from ---> fairest
from fairest ---> creatures
from fairest creatures ---> we
from fairest creatures we ---> desire
from fairest creatures we desire ---> increase
that ---> thereby
that thereby ---> beauty's
that thereby beauty's ---> rose
that thereby beauty's rose ---> might
that thereby beauty's rose might ---> never

Chuyển nhãn sang vector one-hot

Chúng ta sẽ chuyển mỗi nhãn thành vector one-hot có độ dài bằng tổng số từ trong từ điển.

label = ku.to_categorical(label, num_classes=total_words)

Xây dựng mô hình RNN

model = Sequential()
model.add(Embedding(total_words, 100, input_length=max_sequence_len-1))
model.add(Bidirectional(SimpleRNN(150, return_sequences = True)))
model.add(Dropout(0.2))
model.add(SimpleRNN(100)) # h
model.add(Dense(total_words/2, activation='relu', kernel_regularizer=regularizers.l2(0.01)))
model.add(Dense(total_words, activation='softmax'))
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
print(model.summary())

Model: "sequential_4"
_________________________________________________________________
 Layer (type)                Output Shape              Param #   
=================================================================
 embedding_4 (Embedding)     (None, 10, 100)           321100    
                                                                 
 bidirectional_2 (Bidirecti  (None, 10, 300)           75300     
 onal)                                                           
                                                                 
 dropout_2 (Dropout)         (None, 10, 300)           0         
                                                                 
 simple_rnn_3 (SimpleRNN)    (None, 100)               40100     
                                                                 
 dense_4 (Dense)             (None, 1605)              162105    
                                                                 
 dense_5 (Dense)             (None, 3211)              5156866   
                                                                 
=================================================================
Total params: 5755471 (21.96 MB)
Trainable params: 5755471 (21.96 MB)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________
None

Huấn luyện mô hình RNN

history = model.fit(features, label, epochs=130, verbose=1)

Dự đoán 10 từ tiếp theo

test_seq = "despite of wrinkles this thy golden time more survey slain torn slain erred"
next_words = 10

for _ in range(next_words):
  # Chuyển câu thành vector
  token_list = tokenizer.texts_to_sequences([test_seq])[0]

  # Padding câu
  token_list = pad_sequences([token_list], maxlen=max_sequence_len-1, padding='pre')

  # Dự đoán từ tiếp theo
  predicted = model.predict(token_list, verbose=0)

  output_word = ""

  predicted_id = np.argmax(predicted)

  if predicted_id in tokenizer.index_word:
    output_word = tokenizer.index_word[predicted_id]
    test_seq += " " + output_word
  else:
    break

print(test_seq)

Kết quả đầu ra:

despite of wrinkles this thy golden time more survey slain torn slain erred cross hate part new quite stand it words more words

Kết luận

Trong bài học này, chúng ta đã tìm hiểu:

  • Mô hình ngôn ngữ N-Grams.
  • Sự kỳ diệu của Recurrent Neural Networks (RNNs) và khả năng xử lý dữ liệu tuần tự như văn bản, giọng nói. Chúng ta đã khám phá cách RNN ghi nhớ các đầu vào trước, giúp nó phù hợp cho các tác vụ cần ngữ cảnh.
  • Ưu điểm và nhược điểm của RNN.

Tài liệu tham khảo

  • A. Amidi and S. Amidi, “CS 230 - Recurrent Neural Networks Cheatsheet,” Stanford.edu, 2019. https://stanford.edu/~shervine/teaching/cs-230/cheatsheet-recurrent-neural-networks
  • “Recurrent Neural Network Tutorial (RNN),” www.datacamp.com. https://www.datacamp.com/tutorial/tutorial-for-recurrent-neural-network