NLP - Recurrent Neural Network

Nội dung bài viết được tham khảo và dịch lại từ trang blog WILDML.

    Trong bài viết trước, tôi đã giới thiệu với bạn đọc về mô hình ngôn ngữ. Ta đã biết ứng dụng của mô hình ngôn ngữ gồm 2 dạng. Một là đánh giá độ chính xác của một câu dựa theo mức độ tương tự của chúng trên thực tế. Việc đánh giá này giúp ta ước lượng được độ chính xác của văn phạm lẫn ngữ nghĩa của một câu. Những mô hình này thường được ứng dụng trong các hệ thống dịch máy (Machine Translation). Hai là tự động sinh văn bản. Ví dụ huấn luyện mô hình với các tác phẩm của Shakespeare có thể cho phép ta sinh ra các câu từ tựa như cách Shakeapeare viết. Ngoài ra, bạn đọc có thể tham khảo thêm bài viết thú vị này của Andrej Karpathy về khả năng của các mô hình ngôn ngữ mức độ từ vựng.
 
    Trong bài viết này, tôi sẽ trình bày về mô hình ngôn ngữ dựa trên mạng nơ-ron hồi quy (RNN - Recurrent Neural Network), một thuật toán được chú ý rất nhiều trong thời gian gần đây bởi các kết quả tốt thu được trong lĩnh vực xử lý ngôn ngữ tự nhiên. Bài viết này dành cho các bạn đã biết cơ bản về mạng nơ-ron (Neural Network), nếu bạn chưa biết về mạng nơ-ron thì hãy đọc bài viết cài đặt mạng nơ-ron cơ bản. Bài viết đó sẽ giúp các bạn có cái nhìn cơ bản về ý tưởng và cách xây dựng một mạng nơ-ron cơ bản - mạng nơ-ron phi hồi quy.

1. Recurrent Neural Network là gì ?

    Ý tưởng chính của RNN là sử dụng chuỗi các thông tin. Trong các mạng nơ-ron truyền thống tất cả các đầu vào và cả đầu ra là độc lập với nhau. Tức là chúng không liên kết thành chuỗi với nhau. Nhưng các mô hình này không phù hợp trong rất nhiều bài toán. Ví dụ, nếu muốn đoán từ tiếp theo có thể xuất hiện trong một câu thì ta cũng cần biết các từ trước đó xuất hiện lần lượt thế nào chứ nhỉ? RNN được gọi là hồi quy (Recurrent) bởi lẽ chúng thực hiện cùng một tác vụ cho tất cả các phần tử của một chuỗi với đầu ra phụ thuộc vào cả các phép tính trước đó. Nói cách khác, RNN có khả năng nhớ các thông tin được tính toán trước đó. Trên lý thuyết, RNN có thể sử dụng được thông tin của một văn bản rất dài, tuy nhiên thực tế thì nó chỉ có thể nhớ được một vài bước trước đó (ta cùng bàn cụ thể vấn đề này sau) mà thôi. Về cơ bản một mạng RNN có dạng như sau:

A recurent neural network and the unfolding in time of the computation involved in its forward computation. Source: Nature

    Mô hình trên mô tả phép triển khai nội dung của một RNN. Triển khai ở đây có thể hiểu đơn giản là ta vẽ ra một mạng nơ-ron chuỗi tuần tự. Ví dụ ta có một câu gồm 5 chữ, thì mạng nơ-ron được triển khai sẽ gồm 5 tầng nơ-ron tương ứng với mỗi chữ một tầng. Lúc đó việc tính toán bên trong RNN được thực hiện như sau:
  •  $x_t$ là đầu vào tại bước $t$. Ví dụ, $x_1$ là một one-hot vector tương ứng với từ thứ 2 của câu.
  •  $s_t$ là trạng thái ẩn tại bước $t$. Nó chính là "bộ nhớ" của mạng. $s_t$ được tính dựa trên cả các trạng thái ẩn phía trước và đầu vào tại bước đó: $s_t = f(Ux_t + Ws_{t-1}$. Hàm $f$ thường là một hàm phi tuyến như tanh hoặc ReLU. Để tính toán cho phần tử ẩn đầu tiên ta cần khởi tại thêm $s_{-1}$, thường giá trị khởi tạo bằng $0$.
  •  $o_t$ là đầu ra tại bước $t$. Ví dụ, ta muốn dự đoán từ tiếp theo có thể xuất hiện trong câu thì $o_t$ chính là một vector xác suất các từ có trong danh sách từ vựng của ta: $o_t = softmax(Vs_t)$.
    Có một số điều cần ghi nhớ ở đây:
  • Bạn đọc có thể hình dung trạng thái ẩn $s_t$ như là bộ nhớ của mạng. $s_t$ bắt thông tin về những gì đã xảy ra tại tất cả các bước phía trước. Đầu ra $o_t$ được tính toán chỉ dựa trên bộ nhớ ở bước $t$. Như được đề cập ở trên, trong thực tế, $s_t$ không thể bắt được thông tin từ quá nhiều bước phía trước. 
  • Không giống như các mạng học sâu truyền thống sử dụng các tham số khác nhau cho mỗi tầng, RNN sử dụng chung tham số ( $U$, $V$, $W$ ở trên) cho tất cả các bước. Nó phản ánh thực chất ta thực hiện cùng một việc ở mỗi bước, chỉ khác nhau ở đầu vào. Điều này làm giảm tổng số các tham số chúng ta cần phải học.
  • Sơ đồ ở trên có đầu ra tại mỗi bước, tuy nhiên tùy thuộc vào bài toán mà điều này có thể không cần thiết. Ví dụ, khi dự đoán ngụ ý của một câu, ta chỉ quan tâm đến đầu ra cuối cùng, không quan tâm đến ngụ ý của từng từ. Tương tự, ta có thể không cần đầu vào tại từng bước. Đặc trưng chính của RNN là trạng thái ẩn của nó, bắt một số thông tin về câu.

2. Ứng dụng của Recurrent Neural Network

    Trong lĩnh vực xử lý ngôn ngữ tự nhiên (NLP - Natural Language Processing), đã ghi nhận được nhiều thành công của RNN cho nhiều vấn đề khác nhau. Tại thời điểm này, tôi muốn đề cập tới một mô hình phổ biến nhất được sử dụng của RNN là LSTM. LSTM (Long Short-Term Memory) thể hiện được sự ưu việt ở điểm có thể nhớ được nhiều bước hơn mô hình RNN truyền thống. Nhưng bạn không cần phải quá lo lắng vì LSTM về cơ bản giống với cấu trúc của RNN truyền thống, chúng chỉ khác nhau ở cách tính toán của các nút ẩn. Chúng ta sẽ cùng xem chi tiết hơn về LSTM trong bài viết tiếp theo. Còn giờ, ta cùng nhau xem một vài ứng dụng của RNN trong xử lý ngôn ngữ tự nhiên dưới đây.

2.1. Mô hình hóa ngôn ngữ và sinh văn bản

    Mô hình ngôn ngữ cho phép ta dự đoán được xác xuất của một từ nào đó xuất hiện sau một chuỗi các từ đi liền trước nó. Do có khả năng ước lượng được độ tương tự của các câu nên nó còn được ứng dụng cho việc dịch máy. Một điểm lý thú của việc có thể dự đoán được từ tiếp theo là ta có thể xây dựng được một mô hình tự sinh từ cho phép máy tính có thể tự tạo ra các văn bản mới từ tập mẫu và xác xuất đầu ra của mỗi từ. Vậy nên, tùy thuộc vào mô hình ngôn ngữ mà ta có thể tạo ra được nhiều văn bản khác nhau khá là thú vị. Trong mô hình ngôn ngữ, đầu vào thường là một chuỗi các từ (được mô tả bằng one-hot vector) và đầu ra là một chuỗi các từ dự đoán được. Khi huấn luyện mạng, ta sẽ gán $o_t = x_{t+1}$ vì ta muốn đầu ra tại bước $t$ chính là từ tiếp theo của câu.
Dưới đây là một vài nghiên cứu về mô hình hoá ngôn ngữ và sinh văn bản:

2.2. Dịch máy

    Dịch máy (Machine Translation) tương tự như mô hình hóa ngôn ngữ ở điểm là đầu vào là một chuỗi các từ trong ngôn ngữ nguồn (ngôn ngữ cần dịch - ví dụ là tiếng Việt). Còn đầu ra sẽ là một chuỗi các từ trong ngôn ngữ đích (ngôn ngữ dịch - ví dụ là tiếng Anh). Điểm khác nhau ở đây là đầu ra của ta chỉ xử lý sau khi đã xem xét toàn bộ chuỗi đầu vào. Vì từ dịch đầu tiên của câu dịch cần phải có đầy đủ thông tin từ đầu vào cần dịch mới có thể suy luận được.
RNN for Machine Translation. Image Source: http://cs224d.stanford.edu/lectures/CS224d-Lecture8.pdf
Dưới đây là một vài nghiên cứu về dịch máy:

2.3. Nhận dạng giọng nói

    Đưa vào một chuỗi các tín hiệu âm thanh, ta có thể dự đoán được chuỗi các đoạn ngữ âm đi kèm với xác xuất của chúng.
Dưới đây là một vài nghiên cứu về nhận dạng giọng nói:

2.4. Mô tả hình ảnh

    Cùng với ConvNet, RNN được sử dụng để tự động tạo mô tả cho các ảnh chưa được gán nhãn. Sự kết hợp này đã đưa ra được các kết quả khá kinh ngạc. Ví dụ như các ảnh dưới đây, các mô tả sinh ra có mức độ chính xác và độ tường tận khá cao.
Deep Visual-Semantic Alignments for Generating Image Descriptions. Source: http://cs.stanford.edu/people/karpathy/deepimagesent/

3. Huấn luyện Recurrent Neural Network

    Huấn luyện mạng RNN cũng tương tự như các mạng nơ-ron truyền thống, tuy nhiên giải thuật lan truyền ngược (backpropagation) phải thay đổi một chút. Đạo hàm tại mỗi đầu ra phụ thuộc không chỉ vào các tính toán tại bước đó, mà còn phụ thuộc vào các bước trước đó nữa, vì các tham số trong mạng RNN được sử dụng chung cho tất cả các bước trong mạng. Ví dụ, để tính đạo hàm tại \color{deeppink}t = 4$t = 4$ ta phải lan truyền ngược cả 3 bước phía trước rồi cộng tổng đạo hàm của chúng lại với nhau. Việc tính đạo hàm kiểu này được gọi là lan truyền ngược liên hồi (BPTT - Backpropagation Through Time). Lưu ý rằng, với các bước phụ thuộc càng xa thì việc học sẽ càng khó khăn hơn vì sẽ xuất hiện vấn đề hao hụt/bùng nổ (vanishing/exploding) của đạo hàm. Có một vài phương pháp được đề xuất để giải quyết vấn đề này và các kiểu mạng RNN hiện nay đã được thiết kế để triệt tiêu bớt chúng, như Long Short-Term Memory (LSTM) chẳng hạn.

4. Recurrent Neural Network mở rộng

    Trong nhiều năm, các nhà nghiên cứu đã phát triển nhiều kiểu RNN tinh vi để xử lý các nhược điểm của mô hình RNN truyền thống. Chúng ta sẽ xem chi tiết một vài mô hình đó ở các bài viết sau, còn ở bài này, tôi chỉ giới thiệu ngắn ngọn 2 mô hình dưới đây.

4.1. RNN 2 chiều

    Ở mô hình RNN 2 chiều (Bidirectional RNN), đầu ra tại bước $t$\color{blue}t không những phụ thuộc vào các phần tử phía trước mà còn phụ thuộc cả vào các phần tử phía sau. Ví dụ, để dự đoán từ còn thiếu trong câu, thì việc xem xét cả phần trước và phần sau của câu là cần thiết. Vì vậy, ta có thể coi mô hình là việc chồng 2 mạng RNN ngược hướng nhau lên nhau. Lúc này đầu ra được tính toán dựa vào cả 2 trạng thái ẩn của 2 mạng RNN ngược hướng này.

4.2. RNN (2 chiều) sâu

    RNN sâu (Deep (Bidirectional) RNN) cũng tương tự như RNN 2 chiều, nhưng khác nhau ở chỗ chúng chứa nhiều tầng ẩn ở mỗi bước. Trong thực tế, chúng giúp cho việc học ở mức độ cao hơn, tuy nhiên ta cũng cần phải có nhiều dữ liệu huấn luyện hơn.

4.3 Mạng LSTM

    Gần đây, mạng LSTM mà ta đã đề cập một chút ở trên được chú ý và sử dụng khá phổ biến. Về cơ bản mô hình của LSTM không khác mô hình truyền thống của RNN, nhưng chúng sử dụng hàm tính toán khác ở các trạng thái ẩn. Bộ nhớ của LSTM được gọi là tế bào (Cell) và bạn có thể tưởng tượng rằng chúng là các hộp đen nhận đầu vào là trạng thái phía trước $h_{t-1}$ và đầu vào hiện tại $x_t$. Bên trong hộp đen này sẽ tự quyết định cái gì cần phải nhớ và cái gì sẽ xóa đi. Sau đó, chúng sẽ kết hợp với trạng thái phía trước, nhớ hiện tại và đầu vào hiện tại. Vì vậy mà ta có thể truy xuất được quan hệ của các từ phụ thuộc xa nhau rất hiệu quả. Có thể khi mới làm quen với LSTM thì chúng hơi khó hiểu đôi chút, tuy nhiên bạn có thể tham khảo bài viết rất hay này.

    Qua bài viết này, tôi đã giới thiệu tổng quan về mạng Recurrent Neural Network cũng như những ứng dụng của chúng trong thực tiễn.  Trong bài viết tiếp theo, tôi sẽ tiếp tục chuỗi series về xử lý ngôn ngữ tự nhiên (NLP), mà cụ thể là sẽ giải thích rõ hơn về mạng Long Short-Term Memory, một "phiên bản nâng cấp" của RNN mà có thể giải quyết được những nhược điểm mà mạng RNN truyền thống gặp phải. 

Comments

  1. bài này sao chép gần như toàn bộ bài viết ở địa chỉ: https://dominhhai.github.io/vi/2017/10/what-is-rnn/

    ReplyDelete

Post a Comment

Popular posts from this blog

YOLO: You Only Look Once

Intersection over Union (IoU) cho object detection

Giới thiệu về Generative Adversarial Networks (GANs)