From a5df7c797b543deaa7d02ad3edbc118caed60acb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nguy=E1=BB=85n=20Quang=20Ph=C3=BA?= <123137268+pdz1804@users.noreply.github.com> Date: Tue, 5 Nov 2024 01:50:47 +0700 Subject: [PATCH] rm sth --- _posts/2017-4-27-Logistic-Regression.md | 374 ----------- _posts/2017-5-4-SVM.md | 832 ------------------------ _posts/2024-6-14-RNN.md | 167 ----- 3 files changed, 1373 deletions(-) delete mode 100644 _posts/2017-4-27-Logistic-Regression.md delete mode 100644 _posts/2017-5-4-SVM.md delete mode 100644 _posts/2024-6-14-RNN.md diff --git a/_posts/2017-4-27-Logistic-Regression.md b/_posts/2017-4-27-Logistic-Regression.md deleted file mode 100644 index 476af14f..00000000 --- a/_posts/2017-4-27-Logistic-Regression.md +++ /dev/null @@ -1,374 +0,0 @@ ---- -layout: post -title: Logistic Regression -mathjax: true -tags: -- Regression -- Logistic -categories: BasicMachineLearning -description: Trong phần này mình sẽ trình bày về Logistic Regression và giải vài bài toán phân loại cơ bản. ---- -## Giới thiệu về bài toán -Ta sử dụng bài toán [ex4](http://openclassroom.stanford.edu/MainFolder/DocumentPage.php?course=MachineLearning&doc=exercises/ex4/ex4.html) trong khóa học Machine Learning của Andrew Ng. - -Bài toán đưọc mô tả như sau: -Cho tập dữ liệu [ ex4Data.zip ](http://openclassroom.stanford.edu/MainFolder/courses/MachineLearning/exercises/ex4materials/ex4Data.zip) -chứa dữ liệu của 40 sinh viên đậu và 40 sinh viên rớt đại học. Mỗi mẫu \\((x^{(i)}, y^{(i)})\\) chứa điểm số của 2 bài kiểm tra và kết quả thi của một sinh 1 viên. -Nhiệm vụ của ta là xây dựng một mô hình phân loại để ước lượng cơ hội đậu hay rớt của một sinh viên thông qua điểm của 2 bài kiểm tra. - - -Trong tập dữ liệu huấn luyện, ta có: - - -**a.** Cột đầu tiên của dữ liệu X đại diện cho điểm bài thi thứ 1 và cột thứ 2 đại diện cho điểm bài thi thứ 2. -**b.** Vector Y sử dụng '1' là lable cho sinh viên đậu và '0' là lable cho sinh viên rớt. -## Biểu diễn dữ liệu - -Tập dữ liệu được biểu diễn như sau - -![Data](/MLDL/assets/img/LRData.png) - -Với điểm màu đỏ biểu diễn cho sinh viên là đậu và màu xanh là rớt. - -## Tìm lời giải. - -### Hàm Logistic -\\[ \sigma{(t)} = \frac{1}{1+e^{-t}} \\] - -Hàm này có đồ thị như sau: - -![Sigmoid](/MLDL/assets/img/LRSigmoid.gif) - -- Có miền xác định \\( \mathbb{R} \\) và giá trị từ 0 đến 1. -- Tồn đại đạo hàm tại mọi điểm. -- Phù hợp cho việc phân loại (có là 1, không là 0) - -### Tìm hàm mất mát ( *loss function* ) - -Ta gọi -\\( D = {(x^{(1)},y^{(1)}),(x^{(2)},y^{(2)}),...,(x^{(n)},y^{(n)})}, \forall x^{(i)} \in \mathbb{R}^d , y^{(i)} \in \\{0,1\\} \\) -là tập dữ liệu đề cho với n là số lượng điểm dữ liệu. -Mục tiêu của ta là cho dữ liệu của một sinh viên bất kỳ, dự đoán sinh viên đó đậu hay rớt. -\\[ x^{(i)} \Rightarrow \hat{h}^{(i)} \\] -Đặt \\( Y^{(i)} \\) là giá trị của \\( y^{(i)} \\) với đầu vào là \\( x^{(i)} \\). Ta có \\( Y^{(i)} \\) tuân theo phân phối Bernouli. -\\[ Y^{(i)} \sim Bernouli(p,n) \\] - Với: -\\[ p = P{(y=1|x,w)} = \sigma {(w^Tx)} \\] -với \\( w = [w_0, w_1, ..., w_d]^T \\) là tham số cần ước lượng -và \\( x^{(i)} = [1, x ^{(i)} _ {1}, ..., x ^{(i)} _ {d} ]^T \\) -Để thuận tiện trong việc viết, ta đặt \\( \alpha^{(i)} = \sigma (w^Tx^{(i)}) \\) - \\[ q = P{(y=0|x^{(i)},w)} = 1 - p = 1 - \alpha^{(i)} \\] -Từ đó ta suy ra: -\\[ P{(y^{(i)}|x^{(i)},w)} = (\alpha^{(i)})^{y^{(i)}}(1-\alpha^{(i)})^{1-y^{(i)}} \\] -Tức là khi \\( y^{(i)} = 1 \\) vế phải còn lại \\( \alpha^{(i)} \\) và khi \\( y^{(i)} = 0 \\) vế phải còn lại \\( 1 - \alpha^{(i)} \\). Ta muốn mô hình này tốt nhât (Sát giá trị với thực tế nhất) tức là xác suất này phải lớn nhất. -Xét trên toàn bộ tập dữ liệu D. Ta có thể viết lại likelihood của parameters là: -\\[ \begin{eqnarray} L(W) &=& P( \vec{y} | X,W ) \\\ -&=& \prod_{i=1}^{n} P{(y^{(i)}|x^{(i)},w)} \\\ -&=& \prod_{i=1}^{n}(\alpha^{(i)})^{y^{(i)}}(1-\alpha^{(i)})^{1-y^{(i)}} -\end{eqnarray} -\\] -Mục tiêu của ta là maximize giá trị \\( L(w) \\) trên. -### negative log likelihood. -Với hàm số trên, việc tối ưu là rất khó vì khi số \\(n\\) lớn thì -giá trị của \\(P{(y^{(i)}|x^{(i)},w)}\\) sẽ rât nhỏ. -Ta sẽ lầy logarit cơ số e của \\( L(w) \\). Sau đó lấy ngược dấu để được một hàm số mới có giá trị lớn hơn và là một hàm lồi (convex function). Lúc này bài toán ta trở thành tìm giá trị nhỏ nhất của hàm mất mát (hàm này thường được gọi là *negative log likelihood* ). -\\[ J{(w)} = -log( L(w) ) = -\sum_{i=1}^{n}(y^{(i)} log(\alpha^{(i)}) + (1-y^{(i)})log(1-\alpha^{(i)})) \\] -Vì \\( L(w) \in (0,1) \Rightarrow -log(P{(Y|w)}) > 0 \\) -Lúc này ta được \\( J{(w)} \\) làm một hàm lồi nên ta có thể áp dụng các bài phương pháp tối ưu lồi (*convex optimization* ) để giải quyết bài toán này. - -## Gradient Descent method - -Gradient Descent là một phương pháp tối ưu sử dụng phổ biến trong bài toán tối ưu lồi. -Xét khảo sát một hàm số như hình vẽ - -![LRGD](/MLDL/assets/img/LRGD.png) -gọi \\( x\* \\) là điểm cực trị cần tìm của hàm \\(f_{(x)}\\) -Nếu đạo hàm của hàm số tại \\(x_t: f'_ {x_t} > 0 \\) -thì \\(x_t\\) nằm về phía phải so với \\(x\*\\). -Vậy muốn đến được \\(x\*\\) ta cần di chuyển \\(x_t\\) về phía trái. - -Và ngược lại, nếu đạo hàm của hàm số tại \\(x_t: f'_ {x_t} < 0 \\) thì \\(x_t\\) nằm về phía trái so với \\(x\*\\). -Vậy muốn đến được \\(x\*\\) ta cần di chuyển \\(x_t\\) về phía phải. - -Một cách tổng quát, ta cần cộng cho \\(x_t\\) một lượng \\( \Delta \\)ngược dấu với đạo hàm: -\\[ x_{t+1} = x_t + \Delta \\] - -Nếu \\(x_t\\) càng xa \\(x\*\\) thì \\( f'_ {x_t} \\) càng lớn nên lượng \\( \Delta \\) sẽ tỉ lệ với đạo hàm. -Từ đó ta suy ra được: \\[ x_{t+1} = x_t - \alpha f'_ {x_t} \\] -Với \\( \alpha > 0 \\) gọi là learning rate. - -Tổng quát với hàm nhiều biến ta có: -Với hàm \\( h{(X)} = w_0 + x_1w_1 + ... + x_nw_n \\): -\\[ X_{t+1} = X_t -\alpha \nabla_X f_{(X_t)} \\] - -với \\( \nabla_X f_{(X_t)} \\) là gradient của \\(f\\) theo biến \\(X\\) - -**Ví dụ:** -Cho hàm số \\[f{(x)} = x^2 \\] -Với điểm ban đầu \\(x_0 = 2\\) và \\(\alpha = 0.6 \\) ta được: -\\[ f' _ {x} = 2x \\] -\\[ x_{1} = x_0 - \alpha f'_ {x_0} = x_0 - 0.6\times 2x_0 = -0.2x_0\\] -\\[ \Rightarrow x_t = (-0.2)^t \times x_0 \\] -Với t càng lớn thì giá trị \\(x_t\\) càng gần 0 nên kết quả của ta càng chính xác. -Tuy nhiên nếu ta chọn \\(x_0 = 2\\) và \\(\alpha = 0.5 \\) thì: -\\[ x_{1} = x_0 - \alpha f'_ {x_0} = x_0 - 0.5\times 2x_0 = 0\\] -Vậy là ta đã tìm được giá trị cực trị của \\(f{(x)}\\) ngay tại lần lặp đầu tiên. -Từ đó ta thấy việc chọn \\(\alpha\\) và \\(x_0\\) khác nhau sẽ ảnh hưởng đến kết quả và số lần lặp của thuật toán. - -## Newton's method - -Để tìm cực trị của hàm \\( g{(x)} \\), ta cần tìm nghiệm của phương trình \\( g'_ {x} = 0\\). - -Xuất phát từ định lý taylor: -\\[ f{(x)} = f{(x_0)} + f' {(x_0)}.(x-x_0) \\] -Tìm x để \\[ f{(x)} = 0 \\] \\[ \Leftrightarrow f{(x_0)} + f' {(x_0)}.(x-x_0) = 0 \\] -\\[ \Rightarrow x = x_0 - \frac{f{(x_0)}}{f' {(x_0)}} \\] -Đặt \\( f = g' \\) thì nghiệm của phương trình \\( g' {x} = 0\\) là: -\\[ x_{t+1} = x_t - \frac{g' {(x_0)}}{g'' {(x_0)}}\\] -Tổng quá hóa cho hàm nhiều biến: -\\[ X_{t+1} = X_t - \mathbb{H}^{-1} \nabla _ {x} f{(X_t)}\\] -Với \\( H \\) là ma trận Hessian. - -**Ví dụ:** -Cho hàm số \\[ f{(x)} = x^2 -2x + 1 \\] -với điểm ban đầu là \\(x_0 = 3\\) ta được: -\\[ f' {(x)} = 2x - 2 \\] -\\[ f'' {(x)} = 2 \\] -\\[ x_1 = x_0 - \frac{f'}{f''} = x_0 - \frac{2x_0-2}{2} = 1 \\] -Vậy với hàm bậc 2 một biến thì chỉ sau 1 lần lặp ta đã tìm được giá trị cực trị. - -## Giải bài toán - -Trở lại với bài toán ban đầu, ta đã có được 2 phương pháp tối ưu hàm mất mát \\( J \\). -Ta sẽ giải bài này dùng phương pháp tối ưu Newton's method. -Ta có hàm mất mát: -\\[ J{(w)} = -\sum_{i=1}^{n}(y^{(i)} log(\alpha^{(i)}) + (1-y^{(i)})log(1-\alpha^{(i)})) \\] -### Áp dụng công thức Newton: -\\[ w_{t+1} = w_t - \mathbb{H}^{-1} \nabla _ {w} J{(w_t)}\\] -Ta cần phải tính đạo hàm bậc nhất và bậc 2 của hàm mất mát trước. -\\[ log \alpha ^{(i)} = log \frac{1}{1+e^{-w^Tx^{(i)}}} = -log(1+e^{-w^Tx^{(i)}}) \\] -\\[ \frac{\partial log \alpha ^{(i)}}{\partial w_j} = \frac{x _ {j} ^ {(i)} e^{-w^Tx^{(i)}}}{1+e^{-w^Tx^{(i)}}} = x _ {j} ^{(i)} (1 - \alpha ^{(i)} ) \\] -\\[ log(1-\alpha ^{(i)}) = log \frac{e^{-w^Tx^{(i)}}}{1+e^{-w^Tx^{(i)}}} = -w^Tx^{(i)} - log(1+e^{-w^Tx^{(i)}}) \\] -\\[ \frac{\partial log(1-\alpha ^{(i)}) }{\partial w_j} = - x _ {j} ^ {(i)} + x _ {j} ^ {(i)} (1-\alpha^{(i)}) = -\alpha^{(i)}x _ {j} ^ {(i)} \\] -Ta thay vào để tính đạo hàm \\( J{(w)} \\) ta được: - - - -\\[ \begin{eqnarray} \frac{ \partial J{(w)} }{ \partial w_j } &=& - \sum_{j=1}^{n}( y^{(i)} x _ {j} ^ {(i)} (1 - \alpha ^ {(i)} ) - ( 1 - y^{(i)} ) x _ {j} ^ {(i)} \alpha ^ {(i)} ) ~~&(1)& \\\ - &=& - \sum _ {j=1} ^ {n} ( y^{(i)} x _ {j} ^ {(i)} - y^{(i)} x _ {j} ^{(i)} \alpha ^{(i)} - x _ {j} ^ {(i)} \alpha ^{(i)} + y^{(i)} x _ {j} ^ {(i)} \alpha ^{(i)} ) ~~ &(2)& \\\ - &=& - \sum _ {j=1} ^ {n}( y^{(i)} x _ {j} ^{(i)} - x _ {j} ^{(i)} \alpha ^{(i)} ) ~~ &(3)& \\\ - &=& \sum_{j=1}^{n} x _ {j} ^{(i)}( \alpha^{(i)} - y^{(i)} ) ~~ &(4)& -\end{eqnarray} - \\] - - -Một cách tổng quát cho hàm nhiều biến: -\\[ \nabla _ x J = A^T ( \alpha - Y ) \\] -Với : -\\[ -A = -\left\[ -\begin{matrix} - x_{1 1} & x_{1 2} & \dots & x_{1 d} \\\ - x_{2 1} & x_{2 2} & \dots & x_{2 d} \\\ - \vdots & \vdots & \ddots & \vdots \\\ - x_{n 1} & x_{n 2} & \dots & x_{n d} -\end{matrix} -\right\] -\\] - -Tính đạo hàm bậc 2 (Hessian): - -\\[ \partial log \alpha = \frac{\partial \alpha}{\alpha} \\] -\\[ \Rightarrow \partial \alpha = \alpha \partial log \alpha \\] -\\[ \Rightarrow \partial \alpha = \alpha x _ {j} (1 - \alpha ) \\] -Ta thế vào công thức đạo hàm bậc 2 được. - -\\[ \begin{eqnarray} \frac{\partial ^ 2 J(w)}{\partial w_j \partial w_k} &=& \sum _{i=1} ^{n} x ^{(i)} _j \left( \frac{\partial \alpha ^{(i)}}{\partial w_k} \right) \\\ - &=& \sum _ {i=1} ^ {n} x^{(i)} _{j} x ^{(i)} _{k} \alpha ^{(i)} (1 - \alpha ^{(i)}) \\\ - &=& {Z} ^{T} _{j} {B} {Z} _{k} -\end{eqnarray} -\\] -với: - -\\[ {Z}_j = (x ^{(1)} _ j , ..., x^{(n)} _j)^T \\] -\\[ {Z}_k = (x ^{(1)} _ k , ..., x^{(n)} _k)^T \\] -\\[ {B} = \left\[ -\begin{matrix} - \alpha ^{(1)} (1- \alpha ^{(1)}) & & 0 \\\ - & \ddots & \\\ - 0 & & \alpha ^{(1)} (1- \alpha ^{(1)}) -\end{matrix} - \right\] \\] - -Tổng quát cho hàm nhiều biến, ta được: -\\[ {H}_w = \nabla ^ 2 _ w J(w) = {A}^T {B} {A} \\] - -Hiện thực code: -Ở đây ta hiện thực trên ngôn ngữ [julia](julialang.org). Ngoài ra ta cũng có thể hiện thực trên matlab/octave, python,.. một cách tương tự. -Ta chia ngẫu nhiên data thành 2 cặp file. -- `trx.dat` và `try.dat` chứa điểm của 40 sinh viên và nhãn(đậu/rớt) của sinh viên đó dùng để huấn luyện (train) mô hình. -- `tex.dat` và `tey.dat` chứa điểm của 40 sinh viên và nhãn(đậu/rớt) của sinh viên đó dùng để kiểm tra (test) mô hình. - -```python -using PyPlot -x = readdlm("trx.dat"); -y = readdlm("try.dat"); -(m,n) = size(x); -x = reshape(x, m, n); -x = [ones(m,1) x]; - -theta = zeros(n+1,1); -function g(n) - return 1.0 ./(1.0+ exp(-n)) -end - -Iter = 10; -J = zeros(Iter, 1); - -# Loop -for i in 1:Iter - # Calculate the hypothesis fucntion - z = x*theta; - # Calculate sigmoid - h = g(z); - # Calculate gradient and hession. - grad = (1/m) .* x' * (h-y); - H = (1/m) .* x' * diagm(vec(h)) * diagm(vec(1-h)) * x; - # Calculate J for testing convergence - J[i] = (1/m)*sum(-y .* log(h) - (1-y) .* log(1-h)); - theta = theta - H\grad; -end -print(theta) - -print(J) -print(size(theta)) -print( size(x)) - - -tex = readdlm("tex.dat"); -tey = readdlm("tey.dat"); -#print(size(x)); -#print(size(y)); -# -(m,n) = size(tex); -tex = reshape(tex, m, n); -# add x_0 (bias) -tex = [ones(m,1) tex]; -println(size(tex)); - -smx = -10:10 -smy = g(smx) -plot(smx,smy) - -#plot(smx,smy) - -resx = tex * theta; -resy = g(resx); - -println(size(resx),size(resy)) - -plot(resx[1:20],resy[1:20],"r*") -plot(resx[21:40],resy[21:40],"bo") - -clx = -10:10 -cly = 0.5+0.0 *clx -plot(clx,cly) - -succ = 0. -fail = 0. -all = 0. -for i in 1:20 - if resx[i] >= 0.5 - succ +=1 - end -end -println(100. *succ/20) -for i in 21:40 - if resx[i] <0.5 - fail +=1 - end -end -println(100. *fail/20) -println(100 *(succ + fail)/40) - -# loss graph -n_loss = 1:Iter -plot( n_loss, J) -xlabel("epoch") -ylabel("loss") - -``` -Kết quả thu được như sau: - -![LRPlot](/MLDL/assets/img/LRPlot.png) -Với đường màu xanh là đồ thị hàm sigmoid, chấm màu xanh là rớt, chấm đỏ là đậu. -Đồ thị của hàm mất mát J(w) như sau: -![LRPlotLossNT](/MLDL/assets/img/LRPlotLossNT.png) -Nếu lấy sinh viên có giá trị y >= 0.5 là đậu và < 0.5 là rớt thì kết quả là dự đoán là: -Sinh viên đậu: 100.0 % -Sinh viên rớt: 65.0 % -Trung bình: 82.5 % - -Với tập dữ liệu để huấn luyện (training set) là khá nhỏ (40 sinh viên) thì 82.5% là kết quả chấm nhận được. - -### Áp dụng phương pháp Gradient Descent: -Đơn giản hơn phương pháp Newton, ở đây ta chỉ tính đạo hàm cấp 1 của hàm mất mát \\( J(w) \\) và thực hiện lặp. -Ngoài ra ta cần định nghĩa 1 giá trị alpha là Learning rate của thuật toán. -Ở đây ta chọn số lần lặp (iteration) là 500000 và learning rate là 0.005 -Hiện thực code quá trình lặp như sau : -```python -# Set iterations -Iter = 500000; -alpha = 0.005; -J = zeros(Iter, 1); -# Loop -for i in 1:Iter - # Calculate the hypothesis fucntion - z = x*theta; - # Calculate sigmoid - h = g(z); - # Calculate gradient. - grad = (1/m) .* x' * (h-y); #' comment - # Calculate J for testing convergence - J[i] = (1/m)*sum(-y .* log(h) - (1-y) .* log(1-h)); - theta = theta - alpha*grad; -end -print(theta) -``` -Kết quả thu được như sau: -![LRPlot](/MLDL/assets/img/LRPlotGD.png) -Đồ thị hàm mất mát: -![LRPlotLossNT](/MLDL/assets/img/LRPlotLossGD.png) -Nếu lấy sinh viên có giá trị y >= 0.5 là đậu và < 0.5 là rớt thì kết quả là dự đoán là: -Sinh viên đậu: 95.0 % -Sinh viên rớt: 80.0 % -Trung bình: 87.5 % - -Kết quả ở đây tốt hơn sô với Newton's method một chút. - - - -Ta thấy được cả Gradient Descent và Newton's method đều có thể dùng để tối ưu hóa bài toán trên. Tuy kết quả Gradient Descent tốt hơn Newton's method một chút nhưng trên thực tế 2 phương pháp này có độ tốt gần như tương đương nhau. Tuy vậy, người ta vẫn dùng Gradient Descent nhiều hơn so với Newton's method vì: -- Gradient Descent tốn nhiều lần lặp nhưng một lần lặp thời gian thực hiện ngắn hơn. -- Newton's method tuy ít lặp hơn nhưng mỗi lần lặp cần thời gian nhiều hơn vì phải tính đạo hàm cấp 2. -- Việc tính đạo hàm là không đơn giản đặc biệt là tính đạo hàm bậc 2 rất phức tạp nên phương pháp Newton ít được lựa chọn. -Tuy nhiên, nếu số lượng *features* nhỏ ta dùng Newton's method sẽ tốt hơn. -Thông thường nếu số lượng *features* n <= 1000 thì nên dùng Newton's method. Nêu n > 1000 thì nên dùng Gradient Descent. Ở đây features có thể xem là số cột của dữ liệu = 2 nên ta dùng Newton's method việc hội tụ diễn ra nhanh hơn. - -Code, Notebook và data có thể tải tại [đây.](https://github.com/dukn/MachineLearning) - -## Tài liệu tham khảo - -1. [Stanford CS229 Lecture Notes (Notes 1)](http://cs229.stanford.edu/notes/cs229-notes1.pdf) -2. [Machine Learning Cơ bản](http://machinelearningcoban.com) - - - - diff --git a/_posts/2017-5-4-SVM.md b/_posts/2017-5-4-SVM.md deleted file mode 100644 index 1196f66a..00000000 --- a/_posts/2017-5-4-SVM.md +++ /dev/null @@ -1,832 +0,0 @@ ---- -layout: post -title: Support Vector Machine -mathjax: true -tags: -- Classification -categories: BasicMachineLearning -description: Trong phần này mình sẽ trình bày về Support Vector Machine và các lý thuyết đi kèm. ---- - -## Duality -Duality: /dʒuːˈæl.ə.ti/ - ---- -### The Lagrange dual function -**The Lagrangian** - -Xét bài toán sau: - -Tìm giá trị x* nhỏ nhất của hàm số \\( f_0(x) \\) với hàm ràng buộc \\(f_1(x)\\) - -\\[ \begin{eqnarray} x^* = \arg\min_x f_0 (x) ~~&(1)& \\\ -s.t: f_1(x) = 0 ~~&(2)& -\end{eqnarray} -\\] - -Với \\( x = [x_{1}, x_{2}, ..., x_{d}] \\) d là số chiều của dữ liệu \\(x\\). -Miền xác đinh \\( D = dom f_0 \cap dom f_1 \\) với \\(D \ne \phi\\) và hàm mục tiêu và hàm ràng buộc không nhất thiết phải lồi. - -**Định nghĩa nhân tử lagrange (lagrange multiplier)** -Định nghĩa hàm số: -\\[ L(x,\lambda)=f_0 (x) + \lambda f_1(x) -\\] -với biến \\(\lambda\\) gọi là nhân tử lagrange. -Bài toán (1) với ràng buộc (2) có nghiệm là nghiệm của phương trình: -\\[ \nabla _{x,\lambda} L(x,\lambda) = 0 -\\] -Tương đương với: -\\[\nabla _x f_0 (x) + \lambda \nabla _x f_1 (x) = 0 \\\ -f _1 (x) = 0 -\\] - -Phương pháp nhân tử Lagrange cũng được áp cũng nếu bài toán 1 là tìm cực đại. -**Ví dụ 1** - -![SVMElipse](/MLDL/assets/img/SVMElipse.png) - -Cho Elip với phương trình: \\( E = x^2 + 4 y^2 = 4 \\). -Tìm điểm A trên hình sao cho chu vi hình chữ nhật nội tiếp qua A là lớn nhất. - -Từ đó, ta suy ra bài toán tối ưu sau: -Với \\( P = | 4x + 4y| \\) là chu vi hình chữ nhật nội tiếp elip \\(E\\), Tìm max P. -\\[P = |4x + 4y| \\\ - s.t: g(x,y) = x^2 + 4 y^2 = 4 - \\] -\\[ \Rightarrow L(x,y,\lambda) = 4x + 4y + \lambda(x^2 + 4 y^2 - 4) \\] - -Nghiệm của bài toán (7) là nghiệm của phương trình -\\[ \nabla_{x,y,\lambda} L(x,y,\lambda) = 0 \\] -Đạo hàm theo các biến \\(x,y,\lambda\\) ta được hệ: -\\[4 + \lambda 2 x = 0 \\\ -4 + \lambda 2 y = 0 \\\ -x^2+ 4 y^2 = 4 -\\] -suy ra: -\\[ x = \pm \frac{4}{\sqrt{5}}\\\ -y = \pm \frac{1}{\sqrt{5}} -\\] - ---- -### Lagrangian - -Xét bài toán tối ưu tổng quát: -\\[ x^{*} = \arg \min _{x} f_0(x) ~~ (8)\\\ -\text{subject to: } f_i(x) \leq 0, i = 1, 2, \dots, m \\\ -h_j({x}) = 0, j = 1, 2, \dots, p \\] - -Với miền xác đinh \\(\mathcal{D} = (\cap_{i=0}^m \text{dom}f_i) \cap (\cap_{j=1}^p \text{dom}h_j)\\) -Điều kiện: \\( \mathcal{D} \neq \emptyset \\) , và gia trị tối ưu: p*. - -Ta đinh nghĩa Lagrangian \\(L: \mathbb{R}^n \text{x} \mathbb{R}^m \text{x}\mathbb{R}^p \rightarrow \mathbb{R} \\) . -\\[ \mathcal{L}({x}, \lambda, \nu) = f_0({x}) + \sum_{i=1}^m \lambda_if_i({x}) + \sum_{j=1}^p \nu_j h_j({x}) -\\] - -Với \\( \lambda = [\lambda _1, \lambda _2, \dots, \lambda _m]; \nu = [\nu _1, \nu _2, \dots, \nu _p] \\) gọi là dual variables hoặc lagrange multiplier vector. - ---- -### Hàm đối ngẫu Lagrange -Ta định nghĩa "the Lagrange dual function" \\( g: \mathbb{R}^{m} \text{x} \mathbb{R}^{p} \rightarrow \mathbb{R} \\) là giá trị nhỏ nhất của Lagrangian trên \\( x \\). - -\\[ g(\lambda, \nu) = \inf_{x \in D} \mathcal{L}(x,\lambda,\nu) \\\ - = \inf_{x \in D} \left( f_0(x) + \sum_{i=1}^{m} \lambda_i f_i (x) + \sum_{j=1}^{p} \nu_j h_j (x) \right) - \\] - - Với \\(inf\\) là [Infimum](https://en.wikipedia.org/wiki/Infimum_and_supremum). Khi không bị chặn dưới, dual function mang giá trị \\( - \infty \\). - - Lưu ý: với mỗi x, Lagrange là một hàm affine của \\( \lambda,\nu \\) (concave) vậy dual function là inf của một hàm concave cũng là một hàm concave. - ---- -### Chặn dưới của bài toán tối ưu. -Bài toán gốc có giá trị tối ưu p* và \\( \lambda _i > 0, \forall i \text{ và } \nu \\) bất kỳ. Ta có: -\\[ g(\lambda,\nu) \leq p^* ~~ (11) -\\] -Nên \\(g(\lambda,\nu) \\) gọi là chặn dưới của giá trị tối ưu \\(p^*\\). -Điều này được chứng minh như sau: -Giả sử \\(\hat{x}\\) là một điểm feasible thì \\( f_i(\hat{x}) \leq 0 \\) và \\(h_i(\hat{x}) = 0\\) và \\(\lambda \geq 0\\). Tiếp theo ta có -\\[ \sum _{i=1} ^{m} \lambda _i f_i (\hat{x}) + \sum _{i=1} ^{m} \nu_i h_i (\hat{x}) \leq 0 -\\] - -Vì mỗi phần tử trong tổng thứ nhất \\( \leq 0 \\) và thứ tổng thứ 2 \\( = 0 \\) nên: - -\\[ L( \hat{x}, \lambda, \nu) = f_0 ( \hat{x} ) + \sum _{i=1} ^{m} \lambda _i f_i ( \hat{x} ) + \sum _{i=1} ^{m} \nu_i h_i (\hat{x}) \leq f_0 ( \hat{x} ) -\\] - -\\[ g(\lambda,\nu) = \inf_{x \in D} L(x,\lambda,\nu ) \leq L(\hat{x},\lambda,\nu) \leq f_0(\hat{x}) -\\] - -Vì \\( g(\lambda,\nu) \leq f_0(\hat{x} ) \\) đúng với \\( \forall \hat{x} \\) feasible. - - ---- -### Bài toán đối ngẫu Lagrange - -Với mỗi cặp \\( (\lambda , \nu) \\) với \\( \lambda >0 \\). Dual function cho ta một cận dưới của optimal value \\( p^* \\). Do đó, ta có một cận dưới phụ thuộc vào \\( \lambda \text{ và } \nu \\) . -Câu hỏi đặt ra là: Tìm giá trị tốt nhất của cận dưới ta thu được từ hàm đối ngẫu lagrange. -Mở đầu cho bài toán: -\\[ d^{*} = \text{maximize } g( \lambda, \nu ) ~~ (12) \\\ -\text{s.t: } \lambda \geq 0 -\\] -Bài toán này gọi là "Lagrange dual problem" tương ứng với bài toán (8) (primal problem). - -Dual feasible để mô tả cặp \\( (\lambda,\nu) \\) với \\( \lambda \geq 0 \\) và \\( g(\lambda,\nu) > - \infty \\) là feasible set (tập khả thi) của bài toán đối ngẫu. -Ta gọi \\( (\lambda *,\nu *) \\) là nghiệm của bài toán (12) còn được gọi là dual optimal hoặc optimal Lagrange multipliers. -Đây là một bài toán tối ưu lồi vì hàm muc tiêu là 1 concave và hàm ràng buộc là 1 convex. - ---- -### Weak duality -Gọi giá trị tối ưu của bài toán đối ngẫu Lagrange (12) là \\( d^* \\). ( \\( d^* \\) được gọi là "best lower bound on p\*"). Ta được -\\[ d^* \leq p^* ~~ (13) -\\] - -Ngay cả khi bài toán gốc không phải là lồi. Thuộc tính này gọi là weak duality. -Hình minh họa: -![Weak duality](/MLDL/assets/img/Weakduality.png) - ---- -### Strong duality và Slater's constrain qualification - -Nếu dấu "=" tại (13) xảy ra thì đó gọi là strong duality. -Điều này nghĩa là nghiệm tốt nhất của bài toán sẽ tìm được. -Strong duality không thường xuyên xảy ra. -Nếu bài toán gốc (8) là convex tức nó có dạng: -\\[ x^* = \arg\min_{x} f_0(x) ~~ (14)\\\ -\text{subject to: } f_i(x) \leq 0, ~~ i = 1, 2, \dots, m \\\ - Ax = b -\\] -Với \\( f_0, f_1,...,f_m \\) là các hàm lồi thì thường(không phải luôn luôn) có strong duality. -Có những điều kiện ngoài tính chất lồi gọi là constraint qualifications. Một trong những constrain qualifications đơn giản đó là Slater's condition - -**Slater's condition** -Tồn tại điểm x có -\\[ f_i < 0, i = 1,...,m, Ax = b \\] -Điểm này gọi là strictly feasible. -Định lý Slater: nếu tồn tại một điểm strictly feasible (và bài toán gốc là lồi) thì strong duality xảy ra. -Chú ý: -- Strong duality không thường xảy ra, với bài toán lồi. Với bài toán lồi, điều này thường xảy ra hơn. - - ---- -### Complementary slackness (Bù yếu) - -Giả sử rằng strong duality xảy ra. Gọi \\( x^* \\) là điểm optimal của bài toán gốc và \\( ( \lambda^* , \nu^* ) \\) điểm optimal của bài toán đối ngẫu. Điều đó có nghĩa là: -\\[ \begin{eqnarray} f_0( x^{\*} ) &=& g(\lambda^{\*} , \nu^{\*}) \\\ -&=& \inf_x \left( f_0 ( x ) + \sum_{i=1}^{m} {\lambda_i^{\*} f_i(x)} + \sum_{j=1}^{p}{\nu_j^{*}h_i(x)} \right) \\\ -&\leq& f_0( x^{\*}) + \sum_{i=1}^{m} {\lambda_i^{\*} f_i (x)} + \sum_{j=1}^{p}{\nu _j ^{\*} h _i (x)} \\\ -&\leq& f_0 ( x^{\*}) -\end{eqnarray} -\\] - -- Dòng đầu là do strong duality -- Dòng thứ 2 là định nghĩa hàm đối ngẫu -- Dòng thứ 3 là vì infimum -- Dòng thứ 4 là vì \\( f_i( x^* ) \leq 0, \lambda_i \geq 0, i= 1,2,...,m \text{ và } h_j ( x^*) =0 \\). - -Từ đó ta suy ra -\\[\sum_{i=1}^{m} {\lambda_i^{\*} f_i(x)} =0 -\\] -với \\( x^* \\) là giá trị nhỏ nhất của \\( L( x, \lambda^{\*}, \nu^{\*}) \\) và vì mỗi phần tử trên tổng không âm nên ta suy ra tiếp -\\[ {\lambda_i^{\*} f_i(x)} =0 , ~~ i = 1, \dots, m -\\] -Điều kiện này gọi là Complementary slackness. - - ---- -### KKT optimality conditions -Giả sử \\( f_0, f_1, ..., f_m, h_0, ..., h_p \\) khác nhau (và có miền xác đinh). Ta không giả sử nó lồi. -**Đối với bài toán không lồi** - -Giả sử cho \\( x^{\*} \\) và \\( (\lambda ^{\*} , \nu^{\*}) \\) là bất kỳ primal và dual optimal point -Vì tại \\( x^{\*} \text{, } L(x,\lambda^{\*},\nu^{\*}) \\) có giá trị nhỏ nhất nên đạo hàm tại \\( x^{\*} = 0\\). -\\[ \nabla f_0(x^{\*}) + \sum_{i=1}^{m}{\lambda_i^{\*} \nabla f_i(x)} + \sum_{j=1}^{p}{\nu_j^{\*} \nabla h_i } -\\] -Từ đó ta có điều kiện Karush-Kuhn-Tucker (KKT): -Với \\( x^{\*}, \lambda^{\*}, \nu^{\*}\\) - -\\[ \begin{eqnarray} f_i({x}^{\*}) &\leq& 0, ~~ i = 1, 2, \dots, m \\\ -h_j({x}^{\*}) &=& 0, ~~ j = 1, 2, \dots, p \\\ -\lambda_i^{\*} &\geq& 0, ~~ i = 1, 2, \dots, m \\\ -\lambda_i^{\*}f_i({x}^{\*}) &=& 0, ~~ i = 1, 2, \dots, m \\\ -\nabla f_0({x}^{\*}) + \sum_{i=1}^m \lambda_i^{\*} \nabla f_i({x}^{\*}) + \sum_{j=1}^p\nu_j^{\*} \nabla h_j({x}^{\*}) &=& 0 - \end{eqnarray} -\\] -Đây là điều kiện cần để \\( x^{\*}, \lambda^{\*}, \nu^{\*} \\) là nghiệm của bài toán. - -**Đối với bài toán lồi** -Với bài toán lồi và điều kiện Slater thỏa mãn (suy ra strong duality) thì các điều kiện KKT là điều kiện cần và đủ của nghiệm. - -Tóm tắt: -Updating... -\\[...\\] - ---- -## Support vector machine - -### Giới thiệu -![](/MLDL/assets/img/SVM.jpg) -Trong không gian 2 chiều trên, ta cần tìm một đường phân loại 2 class sao cho 2 class nằm về 2 phía của đường phân loại, khoảng cách từ 1 phần từ bất kỳ đến đường phân loại là lớn nhất. -Bài toán tối ưu này gọi là Support vector machine (SVM). - -### Xây dựng bài toán -Ta có tập huấn luyện (training set) là \\( \{(x_1,y_1),(x_2,y_2),\dots,(x_N,y_N)\} \\) với vector \\( x_i = [x_{i1},x_{i1},\dots,x_{iD}]^T \\) với N là số lượng điểm dữ liệu và D là số chiều của dữ liệu. -Giả sử rằng \\( y_i \in \\{ -1, 1 \\}, \forall i \\) với \\( y_i = 1 \\) tương ứng với class 1 và \\( y_i = -1 \\) tương ứng với class 2. -Giả sử: -\\[ \hat{y}(x_i, w, b) = w^T x_i + b = w_{1}x_{i1} + w_{2}x_{i2} + \dots + w_{D}x_{iD} + b = 0 ~~ (15)\\] -là mặt phân cách. Class 1 nằm về phía dương và class 2 nằm về phía âm của \\( \hat{y} \\). -Khoảng cách từ một điểm đến tới mặt phân cách \\( \hat{y} \\) là: -\\[ \frac{sgn(w^Tx_i+b )(w^Tx_i+b )}{||{w}||_2} = \frac{y_i(w^Tx_i+b ) }{||{w}||_2} ~~ (16) -\\] - -Margin được tính là khoảng cách gần nhất từ 1 điểm tới mặt đó. -\\[ margin = \min_{i } \frac{y_i(w^Tx_i+b ) }{||{w}||_2} ~~ (17) -\\] - -Bài toán tối ưu trong SVM là bài toán tìm w và b sao cho margin đạt giá trị lớn nhất. - -\\[ (w^{\*},b^{\*}) = \arg \max _{(w,b)} \left( \frac{y_i(w^Tx_i+b ) }{||{w}||_2} \right) \\\ -= \arg \max _{(w,b)} \left( \frac{1 }{||{w}||_2} \min _{i} y_i(w^Tx_i+b) \right) ~~ (18) -\\] - -Vì w và b là 2 biến số nên ta giả sử \\( y_i(w^Tx_i+b) \geq 1 \\). -Ta đưa bài toán (18) thành bài toán tôi ưu có ràng buộc: -\\[ (w^{\*},b^{\*}) = \arg \max _{(w,b)} \left( \frac{1 }{||{w}||_2} \right) \\\ -\text{s.t: } y_i(w^Tx_i+b) \geq 1, \forall i = 1,2, \dots , N ~~ (19) -\\] -Biến đổi bài toán thành: -\\[ (w^{\*},b^{\*}) = \arg \min _{(w,b)} \frac{1 }{2} {||{w}||_2^2} \\\ -\text{s.t: } 1 - y_i(w^Tx_i+b) \leq 0, \forall i = 1,2, \dots , N ~~ (20) -\\] -Ta có hàm mục tiêu có dạng hàm toàn phương là một hàm lồi và hàm ràng buộc cũng là các hàm lồi nên nó là một bài toán tối ưu lồi, thập chí vì hàm mục tiêu lồi hoàn toàn (strictly convex) nên nghiệm là duy nhất. -Để xác định class cho một điểm sau khi tìm được mặt phân cách \\( \hat{y} \\) ta sử dụng công thức: -\\[ class(x) = sgn(\hat{y}(x)) ~~ (21) -\\] -### Giải bài toán -**Kiểm tra chuẩn Slater** -Điều kiện Slater: nếu tồn tại w,b sao thỏa -\\[ 1- y_i (w^T x_i +b ) < 0 , \forall i = 1,2, \dots , N ~~ (22) -\\] -thì Strong duality thỏa. -Chứng minh: luôn tồn tại \\( w_0, b_0 \\) sao cho -\\[ 1- y_i ( w_0^T x_i + b_0 ) \leq 0, \forall i = 1,2, \dots, N ~~ (23) \\\ -\Leftrightarrow 2- y_i ( 2w_0^T x_i + 2b_0 ) \leq 0, \forall i = 1,2, \dots, N ~~ (23) - \\] -Chọn \\( w_1 = 2w_0 \text{ và } b_1 = 2b_0 \\) ta sẽ có: -\\[ 1- y_i ( w_1^T x_i + b_1 ) \leq -1 < 0, \forall i = 1,2, \dots, N ~~ (25) -\\] -Vậy nên thỏa chuẩn Slater. - -**Lagrangian của bài toán** - -Ta có có Lagrangian của bài toán: - -\\[ L(w,b,\lambda) = \frac{1}{2}{||w||_2^2} + \sum _{i=1}^{N} \lambda _{i} (1 - y_i (w^T x_i + b )) ~~ (26) -\\] - -Với \\( \lambda = [\lambda_1,...,\lambda_N]^T \text{ và } \lambda _i \geq 0, \forall i = 1,2,...,N \\) - -**Hàm đối ngẫu lagrange** -Hàm đối ngẫu của bài toán là: -\\[ g( \lambda ) = \inf _ {( w, b )} L(w, b, \lambda ) = \min _ {( w, b)} L(w, b, \lambda ) ~~ (27) -\\] -Với \\( \lambda \geq 0 \\). -Ta có thể giải vế phải bằng cách giải hệ phương trình gradient của \\( L(w, b, \lambda ) \\) theo w và b bằng 0. -Giải bài toán \\( \nabla _ {( w, b)} g( \lambda ) = 0 \\) ta suy ra hệ: - -\\[ \frac { \partial L (w, b, \lambda ) }{ \partial w } = w - \sum _ {i=1}^{N} \lambda _i y_i x_i = 0 \\\ -\Rightarrow w = \sum _ {i=1} ^ {N} \lambda _i y_i x_i ~~ (28) \\\ -\frac { \partial L (w,b, \lambda ) }{ \partial b } = \sum _ {j=1}^{N} \lambda _j y_j = 0 ~~ (29) -\\] - -Thay kết quả trên vào \\( g( \lambda ) \\) ta được nghiệm - -\\[ g( \lambda ) = \sum _ {i=1}^{N} \lambda _i - \frac {1}{2} \sum _ {j = 1} ^{N} \sum _{k = 1} ^{N} \lambda _j \lambda _k y_j y_k x_j^T x_k ~~ (30) -\\] - -**Bài toán đối ngẫu** -Bài toán đối ngẫu của (26) như sau: -\\[ \lambda ^ {\*} = \arg \max _ {\lambda } g(\lambda ) ~~ (31) \\\ -\text{ s.t: } \lambda \geq 0 ~~ (32) \\\ -\sum _ {i=1}^{N} \lambda _i y_i = 0 ~~ (33) -\\] -Ràng buộc (33) được lấy từ (29). -**Điều kiện KKT** -Đây là bài toán lồi và đã thỏa strong duality nên nghiệm của bài toán thỏa hệ điều kiện KKT sau đây với biến là w, b và \\( \lambda \\): -\\[ \begin{eqnarray} 1 - y_i ( w^Tx_i + b) &\leq& 0 , \forall i = 1, 2, \dots , N ~~ (34) \\\ -\lambda _i &\geq& 0 , \forall i = 1, 2, \dots , N \\\ -\lambda _i ( 1 -y_i (w^T x_i +b ) ) &=& 0 , \forall i = 1, 2, \dots , N ~~ (35) \\\ -w &=& \sum _ {i=1} ^{ N} \lambda _i y_i x_i ~~ ~~ (36) \\\ -\sum _ {i =1 } ^{N} \lambda _i y_i &=& 0 ~~ ~~ ~~ (37) -\end{eqnarray} -\\] - -Giải (35) ta được 2 trường hợp \\( \lambda _i = 0 \\) hoặc \\( 1 -y_i (w^T x_i +b ) = 0 \\). -Trong trường hợp thứ 2 ta suy ra: -\\[ y_i y_i (w^Tx_i + b ) = y_i -\Leftrightarrow w^Tx_i + b = y_i ~~ (38) -\\] - -Trường hợp này chính là những điểm nằm trên đường thẳng \\( \hat{y} = \pm 1 \\). -Những điểm (hay vector) này còn được gọi là giá vector (support vector). - -Tiếp theo, ta gọi \\( S = \\{ n | \lambda _n \neq 0 \\} \text{ và } N_S \\) là số phần tử của S. Với mỗi điểm \\( x_s \in S \\) ta có: -\\[ 1 = y_s(w^Tx_s + b) \Leftrightarrow b = y_s = w^T x_s ~~ (39) -\\] -Ta cũng có thể tính trung bình của b đối với mỗi \\( x_s \\) để tăng tính chắc chắn. -\\[ b = \frac {1}{N_S} \sum _ {s \in S} (y_s - w^Tx_s) = \frac {1}{N_S} \sum _ {s \in S} (y_s - \sum _ {t \in S} \lambda _s y_s x_t^T x_s) ~~ (40) -\\] - -Vậy là ta đã tính được b. Trước đó ta có -\\[ w = \sum _ {i=1} ^{N} \lambda _i y_i x_i ~~ (41) -\\] -ta thay w bà b vừa được tính vào mặt phân cách \\( \hat{y} \\) ta được -\\[ \hat{y} = w^Tx + b = \sum _ {t \in S} \lambda _t y_t x_t^T x + \frac {1}{N_S} \sum _ {s \in S} ( y_s - \sum _ {t \in S} \lambda _s y_s x_t^T x_s ) ~~ (42) -\\] - ---- -### Hiện thực SVM - -Ta sẽ sử dụng thư viện [scikit-learn](http://scikit-learn.org/stable/) trong python để hiện thực cách lập trình nghiệm cho bài toán SVM. -```python -import numpy as np -import matplotlib.pyplot as plt -from sklearn import svm -import random - -# y = 2x - 1 -# Generating data -X = np.array([i/10. + random.random()/2. for i in range(-10,10)]) -Y1 = 2*X - 1 + 2 -Y2 = 2*X - 1 - 2 -for i in range(len(Y1)): - Y1[i] = Y1[i] + random.random() - Y2[i] = Y2[i] + random.random() -Xdata = [] -Ydata = [] -for i in range(len(X)): - Xdata.append([X[i], Y1[i]]) - Xdata.append([X[i], Y2[i]]) - Ydata.append(0) - Ydata.append(1) - -Xdata = np.array(Xdata) -Ydata = np.array(Ydata) - - -clf = svm.SVC(kernel = 'linear', C = 1e6) -clf.fit(Xdata,Ydata) - -# Print support vectors -print clf.support_vectors_ -print -# Print w and b -w = clf.coef_ -b = clf.intercept_ -print w , b - - -# Plot data -for i in range(len(X)): - plt.plot(X[i],Y1[i],'ro') -for i in range(len(X)): - plt.plot(X[i],Y2[i],'bo') - -# Plot classification line -Xline = np.array([-1.2, 2]) -Yline = -1*Xline * w[0][0]/w[0][1] - b[0]/w[0][1] -plt.plot(Xline,Yline) - -plt.show() - - -``` -Kết quả support vectors và w, b như sau: - -```python -[[-0.65991059 -0.22613997] - [-0.30739343 -2.61819165] - [ 1.05506403 0.02238899]] - -[[ 1.26003173 -0.65013722]] [-0.31507677] -``` - -Dữ liệu và đường phân loại được plot ra như hình. - -![HardMargin](/MLDL/assets/img/sklearn.png) - -_Chú ý_ : dữ liệu được sinh ngẫu nhiên nên kết quả mỗi lần thực hiện sẽ khác nhau. - -## Soft Margin - SVM - -Bài toán phân loại 2 class ở trên 2 class được phân loại rõ ràng nhưng nếu 2 class có lẫn lộn nhau 1 phần hoặc có nhiễu (Như hình minh họa bên dưới) thì thuật toán sẽ không thực hiện được. -Từ đó người ta phát triển phương pháp ban đầu (hard margin) thành một phương pháp mới bỏ qua một số điểm cho vào vùng không an toàn. Phương pháp đó gọi là soft margin. - -![Ảnh Minh họa soft margin. Nguồn: internet](/MLDL/assets/img/SVM_sm.png) -Soft margin sẽ là dạng tổng quát của hard margin. -Về cách xây dựng bài toán tương tự như với phần hard margin nên ta sẽ trình bay nhanh qua phần này. ---- -### Bài toán soft margin tổng quát - -Ta gọi \\( \xi \\) là giá trị đại diện cho các điểm phân loại không đúng \\( ( \xi > 1) \\) hoặc nằm trong vùng margin \\( ( 0 < \xi < 1 ) \\). Bài toán soft margin SVM có dạng như sau: -\\[ (w,b, \xi ) = \arg \min _ {w,b, \xi } \frac {1}{2} ||w||^2_2 +C \sum _ {i =1}^{N} \xi _i ~~ (43) \\\ -s.t: 1 - \xi _i - y_i (w^Tx_i +b) \leq 0, \forall i = 1,2,...,N ~~ (44) \\\ --\xi _i \leq 0, \forall i = 1,2,...,N -\\] - -Với C là một hằng số dương và \\( \xi = [ \xi _1 , \xi _2 , \dots, \xi _ N ]^T \\) -### Tiêu chuẩn Slater cho soft margin -Theo đề bài ta có: -\\[ 1-\xi _i - y_i(w^Tx_i +b) \leq 0 \\\ -\Leftrightarrow 1 \geq \xi _i + y_i(w^Tx_i +b) \\\ -\Leftrightarrow \xi _i + y_i(w^Tx_i +b) > 0 \\\ -\\] -Vậy bài toán thỏa tiêu chuẩn Slater - -### Lagrangian của bài toán soft margin -Ta xây dựng được Lagrangian như sau -\\[ L(w,b, \xi , \lambda , \mu ) = \frac {1}{2} ||w||^2_2 + C \sum _ {i=1}^{N} \xi _i + \sum _ {i=1}^{N} \lambda _ i (1- \xi _i-y_i(w^Tx_i+b))- \sum _ {i=1}^{N} \mu _i \xi _i ~~ (45) -\\] -Với \\( \lambda = [ \lambda _1, \lambda _2,..., \lambda _N]^T \succeq 0 \text{ và } \mu = [ \mu _1, \mu 2,..., \mu _N]^T \succeq 0 \\) là các biến đối ngẫu Lagrange. - -### Bài toán đối ngẫu -Hàm đối ngẫu của bài toán như sau: -\\[ g( \lambda , \mu ) = \min _ {(w,b, \xi )} L(w,b, \xi , \lambda , \mu ) ~~ (46) -\\] - -Tương tự với bài toán hard margin, Giá trị nhỏ nhất của vế phải đạt được tại điểm có đạo hàm của \\( L(w,b, \xi , \lambda , \mu ) = 0 \\). Ta có hệ phương trình: -\\[ \frac { \partial L}{ \partial w} = 0 \Leftrightarrow w = \sum _ {i=1}^{N} \lambda _i y_i x_i ~~ (47) \\\ -\frac { \partial L}{ \partial b} = 0 \Leftrightarrow \sum _ {i=1}^{N} \lambda _i y_i =0 ~~ (48) \\\ -\frac { \partial L}{ \partial \xi _i} = 0 \Leftrightarrow \lambda _i = C - \mu _ i ~~ (49) -\\] - -Từ (49) ta suy ra \\( 0 \leq \lambda _i, \mu _i \leq C, i = 1,2,...,N \\). - -Thay các biểu thức trên vào Lagrangian ta suy ra hàm số đối ngẫu: -\\[ g( \lambda , \mu) = \sum _ {i=1}^{N} \lambda _i - \frac {1}{2} \sum _ {i=1}^{N} \sum _ {j=1}^{N} \lambda _ i \lambda _ j y_i y_j x_i^T x_j ~~ (50) -\\] - -Từ đó ta có được bài toán đối ngẫu: -\\[ g( \lambda , \mu ) = \sum _ {i=1}^{N} \lambda _i - \frac {1}{2} \sum _ {i=1}^{N} \sum _ {j=1}^{N} \lambda _ i \lambda _j y_i y_j x_i^Tx_j ~~ (51) \\\ -\text {subject to: } \sum _ {i=1}^{N} \lambda _i y_i ~~ (52) \\\ -0 \leq \lambda _i \leq C , \forall i = 1,2,...,N ~~ (53) -\\] - -### Điều kiên KKT cho bài toán soft margin - -\\[ \begin{eqnarray} 1 - \xi _i - y_i ( w^T x_i + b) &\leq& 0 ~~ (54) \\\ -\- \xi _i &\leq& 0 ~~ (55) \\\ - \lambda _i &\geq& 0 ~~ (56) \\\ - \mu _i &\geq& 0 ~~ (57) \\\ - \lambda _i (1- \xi _i - y_i (w^T x_i +b)) &\leq& 0 ~~ (58) \\\ - \mu _i \xi _i &=& 0 ~~ (59) \\\ - w &=& \sum _ {i=1}^{N} \lambda _i y_i x_i ~~ (60) \\\ - \sum _ {i=1}^{N} \lambda _i y_i &=& 0 \\\ - \lambda _i &=& C - \mu _i - \end{eqnarray} -\\] - -Nếu \\( \lambda _i = 0 \\) suy ra \\( \mu _ i = C \\) suy ra \\( \xi _i =0 \\) nghĩa là không có điểm nào phải bỏ qua. -Nếu \\( \lambda _i > 0 \\) suy ra -\\[ 1- \xi _i = y _i (w^T x_i + b ) -\\] -Nếu \\( 0 < \lambda _i < C \\) suy ra \\( \mu _i \ne 0 \\) suy ra \\( \xi _i = 0 \\) tương đương với \\( y_i (w^T x_i + b) = 1 \\) ( các điểm \\( x_i \\) nằm trên margin). - -Với những điểm \\( \lambda _i >0 \\) sẽ là các support vector. -Đặt \\( M = \\{ n | 0 < \lambda _n < C \\} \text{ và } S = \\{m | 0 < \lambda _m \\} \\). -Suy ra được b và w: -\\[ w = \sum _ {m \in S} \lambda _ m y _ m x _ m \\\ -b = \frac {1} {N_M} \sum _ {n \in M} {(y_n - w^T x)} = \frac {1}{N_M} \sum _ {n \in M} \left( y_n - \sum _ {m \in S} \lambda _m y_m x^T _m x_n \right) -\\] -Thế vào \\( w^T x + b \\) ta được: -\\[ w^T x + b = \sum _ { m \in S} \lambda _ m y _ m x^T _m x + \frac {1}{N_M} \sum _ {n \in M} \left( y_n - \sum _ {m \in S} \lambda _ m y _m x^T_m x_n \right) -\\] - -### Hiện thực soft margin -Ta sẽ hiện thực với tập dữ liệu ex4 giống bài [Logistic Regression](/MLDL/basicmachinelearning/2017/04/27/Logistic-Regression/) -```python -# Import sklearn -from sklearn import svm -# Readfile -fx = open("ex4x.dat").read().strip().split('\n'); - -X = [] -y = [] - -for i in fx: - tmp = i.split() - X.append( [ float(tmp[0]) ,float(tmp[1]) ] ) -fy = open("ex4y.dat").read().split('\n'); -for i in fy[:-1]: - y.append(float(i)) - -clf = svm.SVC(kernel = 'linear'); # Using soft margin -clf.fit(X,y); -w = clf.coef_ -b = clf.intercept_ -print w,b - -from matplotlib import pyplot as plt -import numpy as np -X0 = [X[x0][0] for x0 in range(40)] -X1 = [X[x1][1] for x1 in range(40)] -X2 = [X[x2][0] for x2 in range(40,80)] -X3 = [X[x3][1] for x3 in range(40,80)] -plt.plot( X0, X1, "r+") -plt.plot( X2, X3, "bo") -plt.xlabel('Diem 1') -plt.ylabel('Diem 2') - - -pltx = [15,65]; -w0 = w[0][0] -w1 = w[0][1] -plty = []; -plty.append((-1. / w1) * ( w0 * pltx[0] +b[0])); -plty.append((-1. / w1) * ( w0 * pltx[1] +b[0])); -plt.plot(pltx, plty) -plt.show() - -``` -Output như sau: -```python -[[ 0.10918793 0.12291274]] [-12.51099492] -``` - -![soft margin](/MLDL/assets/img/SVM_sm2.png) - - - -## Kernel SVM - -Soft margin đã giải quyết được vấn đề của 2 class phân loại không hoàn toàn hoặc có nhiễu thế nhưng nó chỉ phân loại tuyến tính (đường phân loại có dạng \\( Ax + b = 0 \\) ). Đối với dữ liệu phân loại không tuyến tính, soft margin cũng sẽ gặp thất bại ngay. -Hình bên dưới cho thấy sự thất bại của soft margin trong một trường hợp dữ liệu phân loại không tuyến tính. - -![Thất bại của soft margin](/MLDL/assets/img/fail.png) - -Nhưng nếu chuyển dữ liệu trên vào một không gian mới từ \\( (x_1, x_2) \text{ đến } (x_1^2, x_2) \\) thì dữ mới trở thành như hình dưới: - -![Dữ liệu khi được đưa vào không gian mới](/MLDL/assets/img/convert.png) - -Ta thấy lúc này dữ liệu đã được phân loại tuyến tính. Ta chỉ cần áp dụng soft margin hoặc các phương pháp phân loại tuyến tính khác đối với bài dữ liệu mới này. - -![Phân loại sau khi đã chuyển dữ liệu sang không gian mới](/MLDL/assets/img/svmconvert.png) - -**Q:** Vậy là đã giải quyết được bài toán trên rồi sao? - -**A:** Đúng vậy! - -**Q:** Nhưng vì sao có thể biết được chuyển sang không gian từ \\( (x_1, x_2) \text{ đến } (x_1^2, x_2) \\) thì dữ liệu sẽ về dạng tuyến tính. - -**A:** Vì khi plot dữ liệu lên ta có thể thấy được chúng phân loại bằng một đường cong dạng Parabol nên sử dụng không gian mới đó. - -**Q:** Với những bài toán khác thì sao? nếu dữ liệu có dạng đường cong phức tạp hoặc nhiều hơn 3 chiều thì việc phân loại và đoán phép biến đổi không gian như trên có còn khả thi không? - -**A:** Việc hiện thị dữ liệu như trên gọi là _Data visualization_ đây là một kỹ thuật đang được phát triển trong khoa học dữ liệu. Có những kỹ thuật hiển thị giúp ta dễ hình dung cũng như tìm ra được những phương pháp xử lý cho bài toán của ta. Thế nhưng không phải dữ liệu nào cũng có thể hiện thị được nên đây cũng là một kỹ thuật còn đang được phát triển. Nếu dữ liệu phức tạp thì đây không phải là cách khả thi để giải quyết bài toán như trên. - -**Q:** Vậy có cách nào khác không? - -**A:** Có! Kernel. - -### Kernel - -Trên ý tưởng đó, ta sẽ biến đổi không gian ban đầu thành không gian mới sử dụng hàm \\( \Phi (x) \\). Đối với ví dụ trên, \\( \Phi (x) = [x_1^2 , x_2]^T \\). -Trong không gian mới, bài toán trở thành: - -\\[ \lambda ^{\*} = \arg \max _ { \lambda } \sum _ {i=1}^{N} \lambda _i - \frac {1}{2} \sum _ {i=1}^{N} \sum _ {j=1}^{N} \lambda _ i \lambda _j y_i y_j \Phi (x_i)^T \Phi (x_j) \\\ -\text {subject to: } \sum _ {i=1}^{N} \lambda _i y_i \\\ -0 \leq \lambda _i \leq C , \forall i = 1,2,...,N -\\] -\\[ f( \Phi (x) ) = w^T \Phi (x) + b = \sum _ {m \in S} \lambda _ m y _ m \Phi (x_m)^T \Phi (x) + \frac {1}{N_M} \sum _ {n \in M} \left( y_n - \sum _ {m \in S} \lambda _ m y_m \Phi (x_m)^T \Phi (x_n) \right) -\\] - -Để tính được \\( \Phi (x) \\) là công việc rất khó, thậm chí \\( \Phi (x) \\) có thể có số chiều rất lớn. -Quan sát các biểu thức trên ta thấy, thay vì tính \\( \Phi (x)\\), ta chỉ cần tính \\( \Phi (x)^T \Phi (z) \\) với 2 điểm \\( x,z \\) bất kỳ. -Kỹ thuật này gọi là *kernel trick*. -Phương pháp dùng kỹ thuật này gọi là *kernel method*. - -Định nghĩa hàm kernel \\( k(x,z) = \Phi (x)^T \Phi (z) \\) Ta viết lại bài toán thành: - -\\[ \lambda ^{\*} = \arg \max _ { \lambda } \sum _ {i=1}^{N} \lambda _i - \frac {1}{2} \sum _ {i=1}^{N} \sum _ {j=1}^{N} \lambda _ i \lambda _j y_i y_j k(x_i , x_j ) \\\ -\text {subject to: } \sum _ {i=1}^{N} \lambda _i y_i \\\ -0 \leq \lambda _i \leq C , \forall i = 1,2,...,N -\\] -\\[ f( \Phi (x) ) = w^T \Phi (x) + b = \sum _ {m \in S} \lambda _ m y _ m k(x_m , x) + \frac {1}{N_M} \sum _ {n \in M} \left( y_n - \sum _ {m \in S} \lambda _ m y_m k(x_m , x_n) \right) -\\] - - -### Tính hàm kernel - -Xét phép biến đổi không gian 2 chiều \\( x = [x_1,x_2]^T \\) thành không gian 5 chiều \\( \Phi (x) = [1, \sqrt {2}x_1, \sqrt {2}x_2, x_1^2, \sqrt {2}x_1x_2, x_2^2 ]^T \\). Ta có: -\\[ k(x,z) = \Phi (x)^T \Phi (z) \\\ -= [1, \sqrt {2}x_1, \sqrt {2}x_2, x_1^2, \sqrt {2} x_1 x_2 , x_2^2 ] [1, \sqrt {2} z_1 , \sqrt {2} z_2 , z_1^2 , \sqrt {2} z_1 z_2 , z_2^2 ]^T \\\ -= 1 + 2x_1z_1 + 2 x_2 z_2 + x_1^2z_1^2 + 2 x_1x_2z_1z_2 + x_2^2 z_2^2 \\\ -= (1+x_1z_1 + x_2z_2)^2 \\\ -= (1+ x^Tz)^2 -\\] - -Từ đó ta thấy việc tính kernel \\(k()\\) với 2 điểm dữ liệu dễ dàng hơn việc tính từng \\(\Phi(x)\\) rồi nhân với nhau. - -### Tính chất của hàm kernel -Hàm kernel thường phải thỏa Mercer’s theorem: -Cho tập dữ liệu \\( x_1,...,x_n \\) và tập các số thực bất kỳ \\( \lambda _1, \dots , \lambda _n \\). Hàm \\( K() \\) phải thỏa: -\\[ \sum _ {i=1}^{n} \sum _ {j=1} ^ {n} \lambda _ i \lambda _ j K(x_i,x_j) \geq 0 -\\] -Điều này có nghĩa là hàm mục tiêu là các hàm lồi. -Trên thực tế cũng có một số hàm mục tiêu không thỏa Mercer's theorem nhưng vẫn được dùng làm kernel vì kết quả chấp nhận được. - -### Các hàm kernel thông dụng - -Trên thực nghiệm, người ta thường sử dụng các hàm kernel thông dụng sau: -+ Linear: -\\[ k(x,z) = x^Tz \\] -+ Polynomial: -\\[ k(x,z) = (r + \lambda x^Tz)^d \\] -Với d là số dương chỉ bật của đa thức. -+ Radial Basic Function -\\[ k(x,z) = exp ( - \lambda ||x-z|| _ 2^2), \lambda >0 \\] -+ Sigmoid: -\\[ k(x,z) = tanh (r+ \lambda x^Tz) \\] - -### Hiện thực kernel SVM - -Ta sẽ sử dụng tập dữ liệu trên để hiện thực việc phân loại bằng kernel SVM - -```python -import numpy as np -import matplotlib.pyplot as plt -from sklearn import svm - -# Dataset -X = np.c_[( -2.9 , 8.91 ), - ( -2.4 , 6.26 ), - ( -1.9 , 4.11 ), - ( -1.4 , 2.46 ), - ( -0.9 , 1.31 ), - ( -0.4 , 0.66 ), - ( 0.1 , 0.51 ), - ( 0.6 , 0.86 ), - ( 1.1 , 1.71 ), - ( 1.6 , 3.06 ), - ( 2.1 , 4.91 ), - ( 2.6 , 7.26 ), - ( 3.1 , 10.11 ), - ( -2.9 , 9.41 ), - ( -2.4 , 6.76 ), - ( -1.9 , 4.61 ), - ( -1.4 , 2.96 ), - ( -0.9 , 1.81 ), - ( -0.4 , 1.16 ), - ( 0.1 , 1.01 ), - ( 0.6 , 1.36 ), - ( 1.1 , 2.21 ), - ( 1.6 , 3.56 ), - ( 2.1 , 5.41 ), - ( 2.6 , 7.76 ), - ( 3.1 , 10.61 ), - ( -2.9 , 9.91 ), - ( -2.4 , 7.26 ), - ( -1.9 , 5.11 ), - ( -1.4 , 3.46 ), - ( -0.9 , 2.31 ), - ( -0.4 , 1.66 ), - ( 0.1 , 1.51 ), - ( 0.6 , 1.86 ), - ( 1.1 , 2.71 ), - ( 1.6 , 4.06 ), - ( 2.1 , 5.91 ), - ( 2.6 , 8.26 ), - ( 3.1 , 11.11 ), - ( -2.9 , 7.91 ), - ( -2.4 , 5.26 ), - ( -1.9 , 3.11 ), - ( -1.4 , 1.46 ), - ( -0.9 , 0.31 ), - ( -0.4 , -0.34 ), - ( 0.1 , -0.49 ), - ( 0.6 , -0.14 ), - ( 1.1 , 0.71 ), - ( 1.6 , 2.06 ), - ( 2.1 , 3.91 ), - ( 2.6 , 6.26 ), - ( 3.1 , 9.11 ), - ( -2.9 , 7.41 ), - ( -2.4 , 4.76 ), - ( -1.9 , 2.61 ), - ( -1.4 , 0.96 ), - ( -0.9 , -0.19 ), - ( -0.4 , -0.84 ), - ( 0.1 , -0.99 ), - ( 0.6 , -0.64 ), - ( 1.1 , 0.21 ), - ( 1.6 , 1.56 ), - ( 2.1 , 3.41 ), - ( 2.6 , 5.76 ), - ( 3.1 , 8.61 ), - ( -2.9 , 6.91 ), - ( -2.4 , 4.26 ), - ( -1.9 , 2.11 ), - ( -1.4 , 0.46 ), - ( -0.9 , -0.69 ), - ( -0.4 , -1.34 ), - ( 0.1 , -1.49 ), - ( 0.6 , -1.14 ), - ( 1.1 , -0.29 ), - ( 1.6 , 1.06 ), - ( 2.1 , 2.91 ), - ( 2.6 , 5.26 ), - ( 3.1 , 8.11 ) -].T - -ln = len(X) -r = ln/2 -Y = [0] * r + [1] * r -# figure number -fignum = 1 - -# fit the model -for kernel in ('sigmoid', 'poly', 'rbf'): - clf = svm.SVC(kernel=kernel, gamma=5, coef0 = 1, degree = 2) - clf.fit(X, Y) - if True: - # plot the line, the points, and the nearest vectors to the plane - fig, ax = plt.subplots() - plt.figure(fignum, figsize=(4, 3)) - plt.clf() - plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1], s=80, - facecolors='None') - plt.plot(X[:r, 0], X[:r, 1], 'ro', markersize = 6) - plt.plot(X[r:, 0], X[r:, 1], 'bs', markersize = 6) - plt.axis('tight') - x_min, x_max = -5, 5 - y_min, y_max = -3, 12 - XX, YY = np.mgrid[x_min:x_max:200j, y_min:y_max:200j] - Z = clf.decision_function(np.c_[XX.ravel(), YY.ravel()]) - # Put the result into a color plot - Z = Z.reshape(XX.shape) - plt.figure(fignum, figsize=(4, 3)) - CS = plt.contourf(XX, YY, np.sign(Z), 200, cmap='jet', alpha = .2) - plt.contour(XX, YY, Z, colors=['k', 'k', 'k'], linestyles=['--', '-', '--'], - levels=[-.5, 0, .5]) - plt.title(kernel, fontsize = 15) - plt.xlim(x_min, x_max) - plt.ylim(y_min, y_max) - plt.xticks(()) - plt.yticks(()) - fignum = fignum + 1 - #pdf.savefig() - #plt.show() -plt.show() - -# Reference from blog: Machinelearningcoban - -``` - -Kết quả được hiển thi như sau: - -- Radial Basic Function (rbf) : - -![Radial Basic Function](/MLDL/assets/img/rbf.png) - -- Polynomial (poly): - -![Polynomial](/MLDL/assets/img/poly.png) - -- Sigmoid: - -![Sigmoid](/MLDL/assets/img/sigmoid.png) - - -Ngoài các kernel phổ biến trên, còn rất nhiều kernel khác như String kernel, Chi-square kernel, histogram intersection kernel,... - -Độ tốt của các Kernel là việc rất khó nói(Có rất nhiều bài báo nghiên cứu việc này), tuy nhiên RBF(Gaussian kernel) thường được dùng nhiều nhất. -Andrew Ng có một vài "tricks" như sau: - -- Use linear kernel (or logistic regression) when number of features is larger than number of observations(number of training examples). -- Use gaussian kernel when number of observations is larger than number of features. -- If number of observations is larger than 50,000 speed could be an issue when using gaussian kernel; hence, one might want to use linear kernel. - - -Kinh nghiệm cá nhân của mình là thử hết :))) -Neural network có thể làm được (đến tốt) mọi trường hợp trên nhưng có lẽ sẽ chậm hơn. -Thêm 1 chú ý nữa, neural network dùng convex optimization. - -Kernel rbf có thể hơi khó hiểu. Mọi người có thể tham khảo thêm tại [đây](https://stats.stackexchange.com/questions/58585/how-to-understand-effect-of-rbf-svm). - - - - - - - - - ---- -## Tài liệu tham khảo -1. [Stanford CS229 Lecture Notes (Notes 3)](http://cs229.stanford.edu/notes/cs229-notes3.pdf) -2. [Convex Optimization](http://stanford.edu/~boyd/cvxbook/) – Boyd and Vandenberghe, Cambridge University Press, 2004. -3. [The Elements of Statistical Learning: Data Mining, Inference, and Prediction](https://www.amazon.com/Elements-Statistical-Learning-Prediction-Statistics/dp/0387848576) -4. [Machine Learning Cơ bản](http://machinelearningcoban.com) - - - - - diff --git a/_posts/2024-6-14-RNN.md b/_posts/2024-6-14-RNN.md deleted file mode 100644 index 83298d1f..00000000 --- a/_posts/2024-6-14-RNN.md +++ /dev/null @@ -1,167 +0,0 @@ ---- -layout: post -title: Mạng neural hồi quy -mathjax: true -tags: -- NLP -- Time Series -- RNN -- LSTM -- GRU -categories: DeepLearning -description: ---- - -## Giới thiệu về Recurrent Neural Network (RNN) - -### Định nghĩa RNN: - -**Recurrent Neural Network - RNN** là một loại mạng nơ-ron nhân tạo được thiết kế để xử lý dữ liệu tuần tự (sequential data). Điểm khác biệt chính của RNN so với các kiến trúc mạng nơ-ron khác như Multilayer Perceptron (MLP) hay Convolutional Neural Network (CNN) nằm ở khả năng ghi nhớ thông tin từ các bước thời gian trước đó. Điều này đạt được thông qua việc sử dụng các kết nối hồi quy (recurrent connections), cho phép thông tin ở các input phía sau sẽ nhận được cả thông tin ở các bước trước đó. - -![Cấu trúc mạng RNN](/MLDL/assets/img/rnn_1.png) - -Trong hình minh hoạ, input \\(x_t\\) nhận dữ liệu đầu vào dạng chuỗi, ví dụ như nhiệt độ ngày thứ \\(t\\) đưa vào cell \\(A\\) tính toán và ra output là \\(h_t\\). Cell A tương tự như một Perceptron nhưng ngoài nhận dữ liệu \\(x_t\\), nó còn nhận thêm dữ liệu \\(h_{t-1}\\) (là output của việc tính nhiệt độ ngày trước đó). Output \\(h_t\\) được tính toán ngoài việc làm output còn là input của bước tiếp theo ứng với input \\(x_{t+1}\\). - -Điểm lưu ý ở đây là ta chỉ có 1 cell \\( A \\), sau mỗi lần truyền input, ta sẽ nhận được 1 ouput \\(h_t\\), việc biểu diễn unfold bên phải cho ta hiểu cách dữ liệu được truyền vào. -Việc này ngĩa là model chỉ dùng 1 bộ tham số trong cell \\( A \\) cho việc học nhiều input, đều đó giúp cho kích thước và số lượng input (timestep) có thể dài hay ngắn mà không cần cố định. - -Mô hình RNN truyền thống cho phép nhận output của step trước vào làm input của step sau, qua đó giúp mô hình có thêm thông tin về các bước trước đó. Ít tham số hơn cũng giúp việc học nhanh hơn và mô hình cố gắng tìm được tham số tổng quát cho kiểu dữ liệu hiện tại. - -### Ưu điểm của RNN trong Xử lý Dữ liệu Tuần tự - -RNN sở hữu nhiều ưu điểm vượt trội so với các kiến trúc mạng nơ-ron khác khi xử lý dữ liệu tuần tự: - -- **Ghi nhớ thông tin từ quá khứ:** RNN có khả năng lưu trữ thông tin từ các bước thời gian trước đó, cho phép nó hiểu được ngữ cảnh và mối quan hệ giữa các phần tử trong chuỗi dữ liệu. - -- **Linh hoạt trong xử lý chuỗi có độ dài khác nhau:** RNN có thể xử lý các chuỗi dữ liệu có độ dài khác nhau mà không cần phải điều chỉnh cấu trúc mô hình. - -- **Chia sẻ tham số giữa các bước thời gian:** RNN sử dụng cùng một tập hợp các tham số cho tất cả các bước thời gian, giúp giảm thiểu số lượng tham số cần học và tăng tốc độ huấn luyện. - - - -## Các kiến trúc RNN phổ biến - -### Cấu trúc của một Recurrent Neural Network Cell (RNN Cell): - -![Cấu trúc của 1 cell RNN truyền thống](/MLDL/assets/img/rnn_cell.png) - -Trong một cell RNN, ta có 2 bộ tham số là \\( W_x \\) và \\( W_h \\) tương ứng với tham số của input hiện tại \\( x_{t} \\) và trạng thái trước đó \\(h_{t-t}\\) và bias \\(b\\) . Output của mạng RNN được tính như sau: - -\\[ h_t = \tanh(W_x x_t + W_h h_{t-1} + b) \\] - -Qua đó ta được \\( h_t \\) vừa là output của bước hiện tại vừa là input của bước tiếp theo. -Đối với bước đầu tiên \\( h_0 \\) sẽ được khởi tạo ngẫu nhiên hoặc đặt 1 giá trị mặc định. -Hàm \\( \tanh \\) thường được sử dụng để làm hàm kích hoạt (activation function) vì output trong range (-1: 1) hữu ích cho nhiều bài toán. Trên thực tế ta có thể thay thế các hàm kích hoạt khác cho phù hợp với bài toán và dữ liệu. - -### Long Short-Term Memory (LSTM): - -Mạng Long Short-Term Memory (LSTM) là mạng RNN hồi quy trên các cell LSTM thay vì trên một RNN cell đơn giản. -LSTM thiết kế để mô hình có thể nhớ được cả thông tin dài hạn trước đó và ngắn hạn từ bước gần nhất. - -Cấu trúc của 1 cell LSTM được biểu diễn như sau: - -![Cấu trúc của 1 cell LSTM](/MLDL/assets/img/lstm.png) - -Tương tự với RNN cell, LSTM bổ sung thêm một đầu vào là \\( C \\) để biểu diễn cho bộ nhớ dài hạn, đầu vào \\( h\\) tương tự với RNN biểu diễn cho bộ nhớ ngắn hạn và nhiều phép tính phức tạp hơn, gọi là các *gate*, chúng ta sẽ cùng bóc tách ý nghĩa của cácstate và gate để xem cách LSTM cell hoạt động: - -1. Forget Gate: là hệ số quyết định bao nhiêu thông tin ở các bước trước đó sẽ được giữ lại, hệ số này được quyết định bởi input của bước đó và giúp cho mô hình điều chỉnh việc sử dụng bao nhiêu thông tin ở hiện tại và bao nhiêu thông tin ở quá khứ để cho ra output. -\\[ f_t = \sigma(W_{fx} x_t + W_{fh} h_{t-1} + b_f) \\] - -Hàm sigmoid \\( \sigma \\) được sử dụng vì có giá trị trong khoảng [0:1] biển thị cho tỉ lệ giữ lại thông tin của bước trước đó. `0` là bỏ qua hoàn toàn và `1` là giữ lại toàn bộ. - -2. Input Gate: tính thông tin của bước hiện tại, ta có 2 thông tin cần được tính là \\( i_t \\) và \\( \tilde{C}_t \\). - -\\[ i_t = \sigma(W_{ix} x_t + W_{ih} h_{t-1} + b_i) \\] - -\\[\tilde{C}_{t}\\] - -\\[= tanh(W_{cx} x_t + W_{ch} h_{t-1} + b_c)\\] - -Với \\( i_t \\) ở đây được gọi là Input gate, hoạt động tương tự như Forget gate \\( f_t \\) là cho phép bao nhiêu thông tin được giữ lại. \\( \tilde{C}_t \\) (candidate cell state) sẽ là thông tin hữu ích ở cell hiện tại, dùng để bổ sung vào bộ nhớ dài hạn Cell state ở bước tiếp theo. - -3. Cell State: như đã giới thiệu trước \\( C_t \\) được xem là bộ nhớ dài hạn, điểm khác biệt chính của LSTM với RNN truyền thống, \\( C_t \\) được tính như sau: - -\\[ C_t = f_i C_{t-1} + \tilde{C}_t i_t\\] - -Hiểu một cách đơn gian, cell state \\( C_t \\) là tổng thông tin của bước trước \\( C_{t-1} \\) và thông tin của bước hiện tại \\( \tilde{C}_t \\), 2 trọng số lần lượt là \\( f_t \\) và \\( i_t \\). Việc tính 2 trọng số riêng biệt giúp mô hình linh hoạt việc lựa chọn giữ lại bao nhiêu thông tin tại bước hiện tại và quá khứ. - -4. Output Gate: - -output cho phép tính ra kết quả hidden state hiện tại \\( h_t \\) như sau: - -\\[ o_t = \sigma(W_{ox} x_t + W_{oh} h_{t-1} + b_o) \\] - -\\[ h_t = o_t \tanh(C_t) \\] - -\\( o_t \\) được tính giống như cách tính của \\( f_t \\) và \\( i_t \\), việc sử dụng hàm sigmoid \\( \sigma \\) cho phép mô hình chọn bao nhiêu thông tin tại cell state \\( C_t \\) được sử dụng là hidden state tại bước hiện tại \\( f_t \\). - - -**Khác nhau của \\( h_t \\) và \\( C_t \\)?** - -Ở mạng LSTM, \\( h_t \\) có ý nghĩa tương tự như \\( h_t \\) ở mạng RNN là dùng làm output của trạng thái hiện tại, và input của trạng thái tiếp theo, việc dùng output của trạng thái hiện tại làm input của trạng thái tiếp theo. \\( C_t \\) giống như 1 bằng chuyền dùng để đứa thông tin về các trạng thái trước đó đi đến trạng thái cuối cùng. Có thể hiểu \\( h_t \\) như bộ nhớ ngắn hạn và \\( C_t \\) như bộ nhớ dài hạn của model. Tuy nhiên, các thông tin này sẽ còn phụ thuộc vào giá trị của các gate (forget gate, input gate và output gate) điều chỉnh chứ không hoàn toàn tách biệt. - - -### Gated Recurrent Unit (GRU): - -Cổng truy hồi đơn vị _Gated Recurrent Unit (GRU)_ được xem là một biến thể của mạng LSTM. Sử dụng ít cổng (gate) hơn, không dùng có Cell state \\( C_t \\) để giúp làm mô hình đơn giản hơn. Cấu trúc GRU mô tả như sau: - -![Cấu trúc của 1 cell GRU](/MLDL/assets/img/gru.png) - -1. Update Gate \\( z_t \\): Quyết định mức độ thông tin từ hidden state trước đó \\( h_{t−1} \\) sẽ được giữ lại và mức độ thông tin mới sẽ được thêm vào. - -2. Reset Gate \\( r_t \\): Quyết định mức độ thông tin từ hidden state trước đó\\( h_{t−1} \\) sẽ bị bỏ qua khi tính toán candidate hidden state \\( \tilde{h}_{t} \\). - -Gộp \\( C_t \\) và \\( h_t \\) lại làm một giúp mô hình trở nên đơn giản, giúp huấn luyện nhanh hơn và phù hợp với các bài toán có dữ liệu không quá nhiều. - -### Bidirectional RNN (B-RNN): - -Mô hình B-RNN là kết hợp thông tin từ cả quá khứ và tương lai để cải thiện dự đoán. Việc này phù hợp với các bài toán cần thông tin về cả phía trước lẫn phía sau của 1 chuỗi cho trước, ví dụ như một câu - -![Cấu trúc của 1 cell B-RNN ](/MLDL/assets/img/brnn.png) - - -## Ứng dụng của RNN - -Xử lý ngôn ngữ tự nhiên (NLP): -- Phân loại văn bản. -- Tạo văn bản (text generation). -- Dịch máy. -- Trả lời câu hỏi. - -Nhận dạng giọng nói: -- Chuyển đổi giọng nói thành văn bản. - -Dự báo chuỗi thời gian: -- Dự báo giá chứng khoán. -- Dự báo thời tiết. - -Các mô hình dạng RNN có nhiều ưu điểm và thế mạnh, tuy nhiên cũng rất khó ứng dụng vì yêu cầu tính toán tuần tự vì dữ liệu cần phải lần lượt đi qua các cell để tính cho step tiếp theo. Tương lai, các mô hình dạng dựa trên Transformer sẽ có các ưu điểm để thay thế các mô hình RNN trong việc xử lý các bài toán phức tạp và yêu cầu xử lý lượng dữ liệu lớn một cách nhanh chóng hơn. - -## References - -[1] Goodfellow, I., Bengio, Y., & Courville, A. (2016). Deep learning. MIT press. - -[2] Nielsen, M. A. (2015). Neural networks and deep learning. Determination Press. - -[3] Rumelhart, D. E., Hinton, G. E., & Williams, R. J. (1986). Learning representations by back-propagating errors. Nature, 323(6088), 533-536. - -[4] Hochreiter, S., & Schmidhuber, J. (1997). Long short-term memory. Neural computation, 9(8), 1735-1780. - -[5] Cho, K., Van Merriënboer, B., Gulcehre, C., Bahdanau, D., Bougares, F., Schwenk, H., & Bengio, Y. (2014). Learning phrase representations using RNN encoder-decoder for statistical machine translation. arXiv preprint arXiv:1406.1078. - -[6] http://www.wildml.com/2015/09/recurrent-neural-networks-tutorial-part-1-introduction-to-rnns/ - -[7] http://karpathy.github.io/2015/05/21/rnn-effectiveness/ - -[8] http://colah.github.io/posts/2015-08-Understanding-LSTMs/ \ No newline at end of file