#!/usr/bin/env python # coding: utf-8 #
# # Deep learning hoạt động ra sao? # #
#


# Feedback xin gửi về [page Machine Learners](https://www.facebook.com/mlearners/) hoặc [group Machine Learners](https://www.facebook.com/groups/485581088316769/). Xem các bài viết khác và download code tại [Github page](https://github.com/khanhptnk/deeplearning-tutorials/) # # # Bài viết hôm nay sẽ: # - Giới thiệu các ứng dụng thường gặp của deep learning # - Mô tả cách thức huấn luyện (train) một hệ thống deep learning # # # ### 1. Ứng dụng của deep learning # # Ứng dụng của deep learning nhiều vô kể và trải rộng ra nhiều ngành khác nhau. Ở đây, mình giới hạn các ứng dụng trong phạm vi các bài toán supervised learning trong natural language processing và computer vision. # # Như chúng ta đã biết, **supervised learning** là một bài toán dự đoán trên một tập dữ liệu. Tập dữ liệu gồm các cặp ví dụ $(x, y)$. Nhiệm vụ của model là, sau khi được huấn luyện trên các cặp $(x, y)$, phải dự đoán chính xác $y$ cho các $x$ chưa được nhìn thấy lúc huấn luyện. Điểm khác biệt giữa supervised learning với unsupervised learning là *label được cho sẵn trong lúc huấn luyện*. # # Tùy theo bài tóan mà $x$ và $y$ có thể mang nhiều dạng khách nhau. Ví dụ, trong computer vision, $x$ có thể là một hình ảnh. Nếu $y$ là một phần tử trong một tập rời rạc nào đó ta được bài toán **image classification** (phân loại ảnh). $y$ cũng có thể là cả một câu văn, như trong bài toán **image captioning** (mô tả ảnh bằng một câu văn). # # # # Đối với natural language processing, $x$ có thể là một câu văn. Đối với **sentiment analysis** (dự đoán thái độ), $y$ có thể là "positive" (tích cực) hoặc "negative" (tiêu cực). Trong **machine translation** (dịch thuật), $y$ đơn giản là phiên bản dịch của $x$ ở một ngôn ngữ khác. # # # ### 2. Biểu diễn dữ liệu # # Dữ liệu trước khi đưa vào model được biểu diễn bằng matrix (ma trận) hay tổng quát hơn là **tensor** (ma trận nhiều chiều). # # Giả sử $x$ là một ảnh màu RGB $m \times n$. $x$ sẽ được biểu diễn bởi bằng một tensor $m \times n \times 3$. Tensor này có 3 channel, tương ứng với ba màu đỏ, xanh lá cây và xanh dương. # # # # Đối với các bài toán về ngôn ngữ, ta thường tiền xử lý dữ liệu và xây dựng **vocabulary** (tập hợp các từ mà ta quan tâm). Ta không muốn vocabulary quá lớn (chạy chậm) hoặc quá nhỏ (bỏ mất nhiều từ quan trọng). Thông thường, ta chọn ra top K từ xuất hiện nhiều nhất để làm vocabulary. # Sau khi xây dựng vocabulary, mỗi từ sẽ ứng với một index (chỉ số) trong đó. Vocabulary chứa một từ đặc biệt là "UNK", dùng để đại diện cho tất cả các từ không nằm trong vocabulary. # # **Ví dụ**: vocabulary là *{con, mèo, chó, gà, trèo, cây, bơi, chạy, UNK}*, từ "mèo" sẽ được chuyển đổi thành index 1. Câu "con mèo mà trèo cây cau" sẽ được chuyển thành dãy "0 1 8 4 5 8". # # Gọi $V$ là số lượng phần tử của vocabulary. Mỗi từ sau đó sẽ được biểu diễn bằng một vector $V$ chiều, trong đó giá trị mọi chiều đều là 0 trừ chiều ứng với từ được biểu diễn mang giá trị 1. Vì thế, vector này được gọi là **one-hot vector**. Trong ví dụ trên, từ "mèo" được biểu diễn thành vector [0, 1, 0, 0, 0, 0, 0, 0, 0]. Biểu diễn của một câu là một tensor gồm vector biểu diễn của các từ trong câu. # ### 3. Batch # # Tập các cặp ví dụ $(x, y)$ dùng để huấn luyện model được gọi là **training set**. Model sẽ đi qua training set nhiều lần để học. Mỗi lần như vậy ta gọi là một **epoch**. # # Đơn giản nhất, ta có thể lần lượt đưa từng cặp ví dụ vào model. Tuy nhiên như thế thì tính toán sẽ rất chậm. Model bây giờ, với sự hỗ trợ của GPU, có khả năng xử lý nhiều ví dụ cùng một lúc. Vì thế, ta chia tập huấn luyện thành các **batch**, mỗi batch gồm nhiều cặp ví dụ. **Batch size** là số lượng cặp ví dụ trong mỗi batch. Trong hầu hết các ứng dụng, ta thường dùng batch size bằng 64. # # # # **Nâng cao**: ta có thể hình dung các cặp ví dụ như các điểm trên một hàm ẩn. Ta không biết công thức của hàm này, nên chỉ có thể dùng các điểm ví dụ để xấp xỉ. Khi huấn luyện model ta cần tính gradient của hàm ẩn này để thay đổi model. Vì thế, trên lý thuyết, thì batch size càng lớn, càng có nhiều điểm để xấp xỉ, nên gradient càng chính xác. Tuy nhiên, theo kinh nghiệm thực tế của mình, nhiều lúc dùng batch size 128 lại không tốt như 64. # ### 4. Model # # Ta có thể hình dung model như một hàm số $f_{\theta}(x)$ với parameter $\theta$ nào đó. Ta cần phân biệt **parameter** (tham số) và **variable** (biến số). Ví dụ hàm số $az^2 + bz + c$ có parameter là $(a, b, c)$ và variable là $z$. Đối với model thì variable chính là $x$. Lưu ý là $y$ không phải là variable, vì khi sử dụng model để dự đoán thì không có $y$ để đưa vào. # # Đối với các bài toán classification, model $f_{\theta}(x)$ sẽ là một phân bố xác suất $P_{\theta}(Y)$ ($Y$ ở đây là một random variable (biến số ngẫu nhiên) chứ không phải là label $y$ của $x$ nhé). $P(Y)$ thể hiện sự chắc chắn của model với từng label. Ví dụ dựa vào hình con mèo ở trên, model đưa ra $P(Y=cat) = 0.9$ và $P(Y=dog) = 0.1$. # ### 5. Loss function # # Trước lúc huấn luyện, ta sẽ khởi tạo $\theta$ một cách random. Dựa vào đâu để từ đó tìm ra một $\theta$ tối ưu? Ta cần một hàm để đo độ chính xác của dự đoán của model. Hàm này gọi là **loss function**. # # Loss function là một hàm số thực không âm có dạng $L(f_{\theta}(x), y)$. Đặc biệt, hàm này phải thuận lợi cho việc tính đạo hàm. Một bên của input của loss function là phán đoán của model $f_{\theta}(x)$, bên còn lại là label thật $y$. Giả sử model đưa ra phán đoán dưới dạng phân bố xác suất, tức là $f_{\theta}(x) = P_{\theta}(Y)$. Nếu model tối ưu thì $P_{\theta}(Y = y) = 1$ và $P_{\theta}(Y \neq y) = 0$, tức là model dồn hết sự chắc chắn vào label $y$. Theo trực giác, ta muốn loss function phải bằng 0 (thấp nhất có thể) trong trường hợp này. # # Một loss function thỏa điều kiện này và thường dùng trong classification là **cross entropy loss**: # # $$L \left( P_{\theta}(Y), y \right) = -\log P_{\theta}(Y = y)$$ # # Ta dễ dàng kiểm chứng là khi $P_{\theta}(Y = y)= 1$ thì $\log 1 = 0$. # ### 6. Huấn luyện # # Huấn luyện gồm hai giai đoạn, **forward** và **backward**, được lặp lại xen kẽ cho tới khi nào model đủ tốt. Để đơn giản, ta giả sử batch size bằng 1. # # Ở giai đoạn **forward**, ta đưa $x$ vào model để tính $P(Y)$. Sau đó dựa vào $P(Y)$ và $y$, ta sẽ tính ra giá trị của loss function. # # # # Ở giai đoạn **backward** (hay còn gọi là back-propagation), ta tính gradient (đạo hàm) của loss function theo $\theta$. Sau đó dùng một **gradient-based optimizer** để thay đổi parameter. # # # # Các gradient based optimizer thay đổi parameter cùng trên một nguyên tắc như sau: # # $$ \theta_{new} = \theta_{old} - \alpha \nabla_{\theta}L$$ với $\nabla_{\theta}L$ là đạo hàm của hàm mất mát theo parameter. $\alpha$ được gọi là **learning rate** hay step size, kiểm soát xem ta muốn thay đổi parameter nhiều hay ít. Các optimizer khác nhau ở cách thay đổi learning rate $\alpha$ theo thời gian. Một số optimizer thường dùng là SGD, RMSProp, AdaDelta, Adam (thịnh hành nhất hiện nay). # ### 7. Parallel # # Như đã nói ở trên, việc chia dữ liệu thành batch phục vụ cho việc học trên nhiều cặp ví dụ cùng một lúc. Khi batch size lớn hơn 1, quá trình huấn luyện được tiến hành song song giữa các ví dụ trên cùng một batch. # # # In[ ]: