Logistic regression – Nghia’s blog

 

1. Giới thiệu

Logistic regression là thuật toán đầu tiên mình muốn giới thiệu trong loạt bài về deep learning, đây là thuật toán đơn giản nhưng lại rất hiệu quả trong bài toán phân loại (Classification).
Logistic regression được áp dụng trong bài toán phân loại nhị phân (Binary classification) tức ta sẽ có hai output, hoặc có thể gọi là hai nhãn (ví dụ như 0 và 1 hoặc cat và non-cat).
Logistic regression thường được sử dụng để so sánh với các thuật toán phân loại khác.

2. Định nghĩa

Hồi quy logistic là một phương pháp phân tích thống kê được sử dụng để dự đoán giá trị dữ liệu dựa trên các quan sát trước đó của tập dữ liệu.

Mục đích của hồi quy logistic là ước tính xác suất của các sự kiện, bao gồm xác định mối quan hệ giữa các tính năng từ đó đự đoán xác suất của các kết quả, nên đối với hồi quy logistic ta sẽ có:
Input: dữ liệu input (ta sẽ coi có hai nhãn là 0 và 1).
Output : Xác suất dữ liệu input rơi vào nhãn 0 hoặc nhãn 1.

logistic regression classification

Nguồn: https://www.geeksforgeeks.org/understanding-logistic-regression

Ở hình trên ta gọi các điểm màu xanh là nhãn 0 và các điểm màu đỏ là nhãn 1 đối với hồi quy logistic ta sẽ biết được với mỗi điểm thì xác xuất rơi vào nhãn 0 là bao nhiêu và xác suất rơi vào nhãn 1 là bao nhiêu, ta có thể thấy giữa hai màu xanh và màu đỏ có một đường thẳng để phân chia rất rõ ràng nhưng nếu các điểm dữ liệu mà không nằm sang hai bên mà nằm trộn lẫn nhiều vào nhau thì ta sẽ phân chia như nào ? khi đó ta sẽ gọi tập dữ liệu có nhiều nhiễu và ta phải xử lí trước các nhiễu đó.

 

3. Thiết lập bài toán

Mình sẽ lấy ví dụ ở bài toán phân loại mèo, trong bài toán này sẽ có hai nhãn là cat và non-cat, input sẽ là bức ảnh. Như ta đã biết một bức ảnh màu sẽ có ba kênh màu là R, G, B với một bức ảnh có kích cỡ là \(w * h \) thì sẽ có tất cả \(w * h * 3\) điểm ảnh ( nhân với 3 vì có ba kênh màu), số điểm ảnh chính là số tính năng của vectơ đầu vào \( \mathbf{x} \). Ở hình dưới ta có thể thấy từ một bức ảnh màu ta sẽ reshape về một vectơ cột \( \mathbf{x} \) để làm input cho mô hình logistic.

Với mỗi bức ảnh ta sẽ có một input \( \mathbf{x} \) nên với \(m\) bức ảnh ta sẽ có \(m\) input, việc lấy \(m\) bức ảnh làm input là bởi vì bài toán học máy có giám sát (có nhãn cho input) cần nhiều dữ liệu đầu vào để train mô hình, một bức ảnh là quá ít để cho mô hình có thể học được.

4. Xây dựng model

Tương tự như bài toán linear regression ta sẽ có một bộ trọng số \( \mathbf{w} \) và hai nhãn, nhãn 0 là non-cat và nhãn 1 là cat việc học của mô hình chính là việc điều chỉnh bộ trọng số \( \mathbf{w} \) sao cho dự đoán đầu ra theo đúng ý muốn của ta, nếu bạn chưa biết về thuật toán linear regression thì các bạn có thể đọc ở đây.

4.1 Kí hiệu

  • Xét trên một điểm dữ liệu ta có input \(\mathbf{x} = [x_1; x_2; \dots; x_n]\) sẽ là một vector cột, ta sẽ ngăn cách các feature(\(x_i\)) bằng dấu “;”. input \( \mathbf{x} \) sẽ có dạng như bên dưới:

\[
\mathbf{x} = \left[
\begin{matrix}
x_1 \\
x_2 \\
\vdots \\
x_n
\end{matrix}
\right]
\]

  • Xét trên toàn bộ bộ dữ liệu ( m điểm dữ liệu) ta sẽ có một vector hàng \(\mathbf{X} = [\mathbf{x}^{(1)}, \mathbf{x}^{(2)}, \dots, \mathbf{x}^{(m)}]\) với mỗi cột là một điểm dữ liệu \(\mathbf{x}^{i}\) ngăn cách nhau bởi dấu “,”:

\[
\mathbf{X} =
[\mathbf{x}^{(1)}, \mathbf{x}^{(2)}, \dots, \mathbf{x}^{(m)}] =
\left[
\begin{matrix}
x_1^{(1)} & x_1^{(2)} & \dots & x_1^{(m)}\\
x_2^{(1)} & x_2^{(2)} & \dots & x_2^{(m)}\\
\vdots & \vdots & \ddots & \vdots & \\
x_n^{(1)} & x_n^{(2)} & \dots & x_n^{(m)}\\
\end{matrix}
\right]
\]
Ta có thể thấy \(\mathbf{X}\) có được bằng cách xếp thành cột các các \(\mathbf{x}^{(i)}\).

  • Bộ trọng số \(\mathbf{w} = [w_1; w_2; \dots; w_n]\) cũng sẽ là một vector cột, ta sẽ ngăn cách các trọng số \(w_i\)  bằng dấu “;” bộ trọng số \(\mathbf{w}\) sẽ có dạng như dưới:

\[
\mathbf{w} = \left[
\begin{matrix}
w_1 \\
w_2 \\
\vdots \\
w_n
\end{matrix}
\right]
\]

  • và ta có chuyển vị của vector \(\mathbf{w}\) sẽ là một vector hàng, các \(w_i\) ngăn cách nhau bằng dấu “,” :
    \[
    \mathbf{w}^T = [w_1, w_2, \dots, w_n]
    \]

  • Xét trên một điểm dữ liệu ta đặt \(z = \mathbf{w}^T\mathbf{x} + b\) (b gọi là bias), và \(a = \sigma{(z)}\):

    \[
    z = \mathbf{w}^T\mathbf{x} + b \\
    a = \sigma{(z)}
    \]

  • Xét trên toàn bộ tập dữ liệu ta đặt \(\mathbf{Z} = [z^{(1)}, z_{(2)}, \dots, z^{(m)}]\) và \(\mathbf{A} = [a^{(1)}, a^{(2)}, \dots, a^{(m)}]\), đây đều là các vector hàng với \(m\) là số điểm dữ liệu:
    \[
    \mathbf{Z} = [z^{(1)}, z^{(2)}, \dots, z^{(m)}] \\
    \mathbf{A} = [a^{(1)}, a^{(2)}, \dots, a^{(m)}]
    \]

Note: Việc kí hiệu \(\mathbf{x}, \mathbf{w}\) là vector cột và \(\mathbf{X}\) có được bằng cách xếp các \(\mathbf{x}^{(i)}\) thành cột là để thuận lợi trong việc tính toán và triển khai code, cách kí hiệu là không bắt buộc nghĩa sao việc tính toán được thuận lợi là được.

4.2 Sigmoid function

Hàm Sigmoid (hay còn gọi là hàm số Logistic) là một hàm số toán học có đường cong dạng hình chữ “S” với công thức như sau:
\[
\sigma(x) = \frac{1}{1+e^{-x}}
\]
Mọi giá trị khi đi qua hàm Sigmoid sẽ nằm trong miền giá trị số thực chạy từ 0.0 đến 1.0, Đồ thị hàm sigmoid:

sigmoid

Nguồn: quora.com/What-does-an-x-axis-represent-in-a-logistic-regression-sigmoid-function

Nhìn vào đồ thị trên ta có thể thấy giá trị khi đi qua hàm sigmoid sẽ tiệm cận đến \(1\) khi đầu vào tiến đến \(\infty\) và sẽ tiệm cận đến \(0\) khi đầu vào tiến đến \(-\infty\) và sẽ bằng \(0.5\) khi \(x = 0\).
Nhờ vào đặc tính này mà hàm sigmoid được sử dụng nhiều trong lĩnh vực trí tuệ nhân tạo với vai trò là hàm kích hoạt( hàm kích hoạt giúp định nghĩa đầu ra khi có một input đi qua nó).

Tính chất:
– Là một hàm số liên tục và nhận giá trị trong khoảng \((0;1)\) (\(\exists x\) với \(\forall c\) ta có \(\lim_{x \rightarrow c}f(x) = f(c)\))
– Chính vì là hàm liên tục nên hàm sigmoid sẽ có đạo hàm tại mọi điểm.

Đạo hàm:

\[
\frac{ \partial {\sigma(x)}}{\partial{x}} =
\frac{e^{-x}}{(1+e^{-x})^2} =
\left(\frac{1}{1+e^{-x}} \right)
\left(1 – \frac{1}{1+e^{-x}} \right) =
(\sigma(x))(1 – \sigma(x))
\]

4.3 Model

Tất cả các dạng hồi quy thực tế có cùng chung một phương trình tổng quát để giúp chỉ ra rằng biến mục tiêu \(y\)(biến phụ thuộc) sẽ thay đổi như nào dựa vào mối quan hệ của nó với tất cả các biến độc lập \(x\) mà không quan tâm đến việc mối quan hệ đó là phi tuyến hay tuyến tính:
\[
y = w_nx_n + w_{n-1}x_{n-1} + \dots + w_1x_1 + w_0 + \epsilon
\]
Trong đó:
– \(w_0\) là giá trị ước lượng của y khi tất cả các \(x_i\) đều đạt giá trị \(0\).
– \(\epsilon\) là sai số thể hiện các yếu tố chưa thể nghiên cứu đến nhưng các yếu tố này vẫn ảnh hưởng tới \(y\).
– \(w_i\) là tham số ước lượng(hay ta còn gọi là trọng số), có thể hiểu nôm na là mỗi \(w_i\) sẽ chịu trách nhiệm quản lí một \(x_i\) và \(w_i\) sẽ điều chỉnh để có giá trị \(y\) mong muốn, lưu ý là giá trị tham số \(w_i\) có thể thay đổi còn giá trị \(x_i\) là cố định.
Khi thiết lập mô hình hồi quy ta quan tâm đến quan hệ giữa nhiều biến độc lập \(x_i\) với biến mục tiêu(biến phụ thuộc), phương trình tổng quát để ước lượng biến mục tiêu \(y\):
\[
E(y) = w_nx_n + w_{n-1}x_{n-1} + \dots + w_1x_1 + w_0 = \mathbf{w}^T\mathbf{x} + w_0
\]
Lưu ý là giá trị \(\epsilon\) đã được loại bỏ.
\(E(y)\) trong phương trình logistic regression là xác suất để kết luận giá trị của biến \(y\) không phải giá trị thực của biến \(y\):
\[
E(y) = P( y = 0 || 1|x_1, x_2, \dots, x_n)
\]
Áp dụng hàm sigmoid để chuyển giá trị \(\mathbf{w}^T\mathbf{x} + w_0\) thành xác suất để kết luận giá trị của biến y từ đó để xác định được nhãn của input \(\mathbf{x}\):
\[
P = \frac{1}{1 + e^{-(\mathbf{w}^T\mathbf{x} + w_0)}}
\]
Đây chính là mô hình của logistic regression.

4.4 Loss function

Trước khi đi vào xây dựng hàm mất mát(loss function) cho hồi quy logistic ta thử đi định nghĩa hàm mất mát là gì, tại sao phải cần đến nó.
Như ta đã biết đối với hồi quy tuyến tính(linear regression) hàm mất mát được xây dựng giữa sự sai khác giữa giá trị dự đoán \(\hat{y}\) và giá trị thực \(y\), hàm mất mát của hồi quy tuyến tính được định nghĩa như sau:
\[
J(\mathbf{w}) = \frac{1}{2}(y – \hat{y})^2
\]
Xét trên tập dữ liệu có số điểm dữ liệu là \(m\) ta có hàm mất mát trên cả tập dữ liệu của hồi quy tuyến tính:
\[
\mathcal{L}(\mathbf{w}) = \sum_{i=1}^m\frac{1}{2}(y – \hat{y})^2
\]
Hàm này có tên gọi là Mean Squared Error(MSE)
Mục tiêu của việc cho mô hình học là ta đi điều chỉnh bộ trọng số \(\mathbf{w}\) sao cho giá trị hàm mất mát đạt giá trị nhỏ nhất.

Như vậy: Hàm mất mát trong thuật toán học có giám sát(supervised learning) nói chung là hàm số để đo sự sai khác giữa giá trị thực tế và giá trị mô hình dự đoán, sự sai khác có thể sai khác về giá trị thực(như trong hồi quy tuyến tính) hoặc sai khác về nhãn(như trong bài toán phân loại) việc định nghĩa sự sai khác như nào là tùy vào từng bài toán cụ thể để từ đó xây dựng hàm mất mát.

Đối với hồi quy logistic ta sẽ không sử dụng hàm loss như hồi quy tuyến tính mà ta sẽ đi xây dựng một hàm mất mát phù hợp hơn, lí do tại sao không sử dụng hàm mất mát như hồi quy tuyến tính mình sẽ giải thích ở cuối phần này.

Ta giả sử xác suất để input \(\mathbf{x}\) rơi vào nhãn \(1\) là \(\sigma({\mathbf{w}^T\mathbf{x} + b})\) như vậy xác suất để input \(\mathbf{x}\) rơi vào nhãn \(0\) sẽ là \(1 – \sigma({\mathbf{w}^T\mathbf{x} + b})\). Lưu ý rằng đối với hồi quy logistic trong bài viết này ta sẽ có hai nhãn là \(0\) và \(1\), \(\sigma\) là hàm sigmoid. Đặt \(a = \sigma({\mathbf{w}^T\mathbf{x} + b})\), theo phân phối Bernoulli ta có:
\[
P(y|\mathbf{x};\mathbf{w}) = a^y(1 – a)^{1-y} ~~ (1)
\]
Trong đó:
– \(P(y|\mathbf{x};\mathbf{w})\) là xác suất rơi vào nhãn y với input \(\mathbf{x}\) và bộ trọng số \(\mathbf{w}\).
– \(y\) nhận giá trị là \(0\) hoặc \(1\).
– \(a\) là giá trị mà mô hình dự đoán, giá trị này là xác suất.

Mình sẽ lấy ví dụ cho dễ hiểu: từ phương trình \((1)\) ta thấy, nếu nhãn của input \(\mathbf{x}\) là \(1\) như vậy thay \(y =1\) vào phương trình \((1)\) ta có \(P(y|\mathbf{x};\mathbf{w}) = a\), nếu nhãn của input \(\mathbf{x}\) là \(0\) như vậy thay \(y =0\) vào phương trình \((1)\) ta có \(P(y|\mathbf{x};\mathbf{w}) = 1 – a\)
\[
P(y = 1|\mathbf{x};\mathbf{w}) = a ~~ (2) \\
P(y = 0|\mathbf{x};\mathbf{w}) = 1 – a ~~ (3)
\]
Thực ra phương trình \((1)\) là cách viết gộp của phương trình \((2)\) và phương trình \((3)\).
Phương trình \((1)\) khi xét trên toàn bộ tập dữ liệu ta có:
\[
P(\mathbf{y}|\mathbf{X};\mathbf{w}) = \prod_{i=1}^mP(y^{(i)}|\mathbf{x}^{(i)};\mathbf{w}) = \prod_{i=1}^m(a^{(i)})^{y^{(i)}}(1 – a^{(i)})^{1-y^{(i)}} ~~ (4)
\]
Mục tiêu của ta là ước lượng được giá trị của bộ trọng số \(\mathbf{w}\) sao cho \(P(\mathbf{y}|\mathbf{X};\mathbf{w})\) đạt giá trị cực đại:
\[
\mathbf{w} = \arg\max_{\mathbf{w}}P(\mathbf{y}|\mathbf{X};\mathbf{w}) ~~ (5)
\]
\(\arg\max_{\mathbf{w}}P(\mathbf{y}|\mathbf{X};\mathbf{w})\) còn được gọi là likelihood function.
Việc của ta là ước lượng được bộ trọng số \(\mathbf{w}\) sao cho hàm mất mát đạt cực tiểu, ở phương trình \((4)\) ta đang tìm tìm \(\mathbf{w}\) sao cho \(P\) đạt giá trị lớn nhất vì thế khi ta thêm dấu “-” đằng trước thì lúc này bài toán trở thành ước lương bộ trọng số \(\mathbf{w}\) sao cho \(-P(\mathbf{y}|\mathbf{X};\mathbf{w})\) đạt giá trị nhỏ nhất:
\[
\mathbf{w} = \arg\min_{\mathbf{w}}-P(\mathbf{y}|\mathbf{X};\mathbf{w}) = \arg\min_{\mathbf{w}}-\prod_{i=1}^m(a^{(i)})^{y^{(i)}}(1 – a^{(i)})^{1-y^{(i)}} ~~ (6)
\]
Ta đã biết tích \((a^{(i)})^{y^{(i)}}(1 – a^{(i)})^{1-y^{(i)}}\) là một số nhỏ hơn hoặc bằng 1 như vậy nếu xét với toàn bộ tập dữ liệu ta thấy sẽ biểu thức \(\prod_{i=1}^m(a^{(i)})^{y^{(i)}}(1 – a^{(i)})^{1-y^{(i)}}\) sẽ có rất nhiều giá trị bé hơn hoặc bằng 1 nhân với nhau và tạo thành mốt số rất bé, nếu lấy phương trình \((6)\) làm hàm mất mát thì sẽ gây ra hiện tượng giá trị của hàm mất mát quá bé và gây ra khó khăn cho việc cập nhật bộ trọng số \(\mathbf{w}\)( việc bộ trọng số \(\mathbf{w}\) thay đổi giá trị hay được cập nhật giá trị như nào là phụ thuộc vào đạo hàm hàm mất mát) như vậy ta không thể dùng phương trình \((6)\) làm hàm mất mát mà ta phải biến đổi một chút, ta sẽ dùng hàm \(\log\) để biến tích thành tổng, chú ý ở đây sẽ là hàm \(\log\) tự nhiên tức là hàm \(\ln\) như vậy phương trình \((6)\) trở thành:
\[
\mathbf{w} = \arg\min_{\mathbf{w}}\log(-\prod_{i=1}^m(a^{(i)})^{y^{(i)}}(1 – a^{(i)})^{1-y^{(i)}}) = \arg\min_{\mathbf{w}}-\sum_{i=1}^m(y^{(i)}\log{a^{(i)}} + (1 – y^{(i)})\log{(1 – a^{(i)}}))
\]
Như vậy ta sẽ coi hàm mất mát của hồi quy logistic, hàm này còn có tên gọi là Cross-Entropy:
\[
\mathcal{L}(\mathbf{w}) = -\sum_{i=1}^m(y^{(i)}\log{a^{(i)}} + (1 – y^{(i)})\log{(1 – a^{(i)}}))
\]
Còn bây giờ ta sẽ đi tìm lí do hồi quy logistic không dùng loss function giống như ở linear regression mà mình đã bảo ở đầu phần này.
Ta đã biết là thuật toán Gradient descent để đi tìm cực tiểu của hàm số, nhưng ta chỉ có thể tìm được cực tiểu hàm số khi sử dụng thuật toán này là khi hàm số là một hàm lồi, vậy nếu hàm số không phải hàm lồi thì sao ?
Khi không phải hàm lồi thì hàm số sẽ không có điểm cực tiểu hoặc có rất nhiều điểm cực tiểu, điều này làm cho thuật toán gradient descent không thể tìm được điểm cực tiểu nhất cho hàm số(global minimum point), dẫn đến không thể tối thiểu được hàm mất mát hoặc khó khăn trong việc tối thiểu hàm mất mát.

 

convex and non-convex

Nguồn: https://www.researchgate.net/figure/Convex-and-nonconvex-functions-A-function-g-is-a-convex-function-if-domain-of-g-is-a_fig4_226717592

Ta nhìn vào hình ảnh trên có thể thấy ở hình bên trái là hàm lồi (convex), hàm này có một điểm cực tiểu nên điểm này cũng chính là global minimum point của hàm này luôn, hình bên phải là hàm không lồi (non-convex) hàm này có hai điểm cực tiểu như vậy khi dùng thuật toán gradient descent cho hình bên phải nếu may mắn ta có thể tìm được điểm cực tiểu nhất (global minimum point), nếu không may ta sẽ tìm được điểm chưa cực tiểu nhất(local minimum point).
Nhìn vào đồ thị hàm số thì ta có thể nhận biết được đâu là hàm convex nhưng đối với các hàm số phức tạp ta không thể vẽ đồ thị để nhận biết được mà ta dùng một cách khác là đi tìm đạo hàm bậc hai của hàm số. Khi xét tính lồi của hàm \(f(x)\) ta có:
\[
f”(x) \geq 0 \Rightarrow \textrm{Hàm lồi}\\
f”(x) < 0 \Rightarrow \textrm{Hàm không lồi}
\]

Ta giờ sẽ đi tìm đạo hàm bậc hai theo \(\mathbf{w}\)của hai phương trình dưới đây:
\[
J(\mathbf{w})  = ( y – \hat{y})^2 = (y -(\mathbf{w}^T\mathbf{x} + b))^2 (7) \\
J(\mathbf{w}) = ( y – \hat{y})^2 = \left( y – \frac{1}{1 + e^{-(\mathbf{w}^T\mathbf{x} +b)}}\right)^2 ~~(8)
\]
Ở đây để cho đơn giản mình đang xét với chỉ một điểm dữ liệu nên các chỉ số \(i\) được loại bỏ khỏi các điểm dữ liệu, ví dụ \(y^{(i)}\) bây giờ sẽ là \(y\) và \(\mathbf{x}^{(i)}\) sẽ là \(\mathbf{x}\) và số \(\frac{1}{2}\) cũng được loại bỏ khỏi phương trình. Phương trình \((7)\) chính là hàm loss của liner regression (MSE đối với liner regression), và phương trình \((8)\) chính là hàm loss của logistic regression khi ở dạng MSE. Ở trường hợp đang xét hàm loss của liner regression và logistic regression đều có dạng giống nhau (MSE) chỉ khác nhau ở \(\hat{y}\)(giá trị dự đoán).

Mục đích của ta là đang xét tính lồi của phương trình \((7)\) và \((8)\), để làm như vậy ta phải đi tìm đạo hàm bậc hai theo \(\mathbf{w}\) của hai phương trình này.

Đạo hàm phương trình \((7)\):
Ta có: \(\hat{y} = \mathbf{w}^T\mathbf{x} + b\) nên \(\frac{\partial{\hat{y}}}{\partial{\mathbf{w}}} = \mathbf{x}\)
* Đạo hàm bậc nhất theo \(\mathbf{w}\):
\[
g(\mathbf{w}) = \frac{\partial{J(\mathbf{w})}}{\partial{\mathbf{w}}} = -2\mathbf{x}(y – \hat{y})
\]
* Đạo hàm bậc hai theo \(\mathbf{w}\):
\[
\frac{\partial^2{J(\mathbf{w})}}{\partial{\mathbf{w}^2}} = \frac{\partial{g(\mathbf{w})}}{\partial{\mathbf{w}}} = -2\left( \frac{\partial{(y -\hat{y})}}{\partial{\mathbf{w}}}\mathbf{x} +  (y -\hat{y})\frac{\partial{\mathbf{x}}}{\partial{\mathbf{w}}}\right) = -2((-\mathbf{x})\mathbf{x} + 0) = 2\mathbf{x}^2 \geq 0
\]
Vậy ta đã thấy khi đạo hàm bậc hai theo \(\mathbf{w}\) hàm mất mát của liner regression ta được kết quả là lớn hơn \(0\) vậy hàm mất mát này là hàm lồi(có thể dùng thuật toán gradient descent để tìm cực tiểu) bây giờ ta sẽ xét tiếp tính lồi hàm mất mát của logistic regression với hàm mất mát thuộc dạng MSE.

Đạo hàm phương trình \((8)\):
Ta có: \(\hat{y} = \frac{1}{1+ e^{-(\mathbf{w}^T\mathbf{x} +b)}}\) nên \(\frac{\partial{\hat{y}}}{\partial{\mathbf{w}}} = \mathbf{x}(1-\hat{y})\hat{y}\)

*Đạo hàm bậc nhất theo \(\mathbf{w}\):
\[
g(\mathbf{w}) = \frac{\partial{J(\mathbf{w})}}{\partial{\mathbf{w}}} = -2\mathbf{x}(y – \hat{y})(1 – \hat{y})\hat{y} = -2\mathbf{x}( y\hat{y} – \hat{y}^2 -y\hat{y}^2 + \hat{y}^3)
\]
*Đạo hàm bậc hai theo \(\mathbf{w}\):
\[
\begin{align}
\frac{\partial^2{J(\mathbf{w})}}{\partial{\mathbf{w}^2}}
&= \frac{\partial{g(\mathbf{w})}}{\partial{\mathbf{w}}}\\
&= -2\mathbf{x}\frac{\partial{(y\hat{y} – \hat{y}^2 -y\hat{y}^2 + \hat{y}^3)}}{\partial{\mathbf{w}}} \\
&= -2\mathbf{x}[y\mathbf{x}(1-\hat{y})\hat{y} – 2\hat{y}\mathbf{x}(1-\hat{y})\hat{y} – 2y\hat{y}\mathbf{x}(1-\hat{y})\hat{y} +3\hat{y}^2\mathbf{x}(1-\hat{y})\hat{y}] \\
&= -2\mathbf{x}^2\hat{y}(1-\hat{y})(3\hat{y}^2-2y\hat{y}-2\hat{y} + y) ~~~~~~~~~~~~~~~~~~~~~ (9)
\end{align}
\]
Mục đích của ta là đi tìm xem phương trình \((9)\) lớn hơn hay bé hơn \(0\).
Ta dễ thấy \(\mathbf{x}^2\hat{y}(1-\hat{y})\)  luôn lớn hơn hoặc bằng 0 vì \(\hat{y} \in [0,1]\), tức giờ ta chỉ cần xét hàm số sau:
\[
f(\hat{y}) = -2(3\hat{y}^2-2y\hat{y}-2\hat{y} + y)  ~~ (10)
\]
Ta thấy \(y\) chỉ nhận giá trị \(0\) hoặc \(1\), thay vào (10) ta có:
\[
\begin{align}
\begin{cases}
f(\hat{y}) = -2(3\hat{y}^2-  2\hat{y} – 2\hat{y} + 1)  = -6(\hat{y}-1)(\hat{y} – \frac{1}{3}) ~~ (y=1) ~~ (11)\\
f(\hat{y}) = -2(3\hat{y}^2 – 2\hat{y}) = -4\hat{y}(\frac{3}{2}\hat{y} -1)  ~~ (y=0) ~~(12)
\end{cases}
\end{align}
\]
Đối với phương trình \((11)\) ta thấy với \(\hat{y} \in [0,\frac{1}{3}]\) thì phương trình \((11)\) sẽ \(\leq 0\)
Đối với phương trình \((12)\) ta thấy với \(\hat{y} \in [\frac{2}{3},1]\) thì phương trình \((12)\) sẽ \(\leq 0\)
Từ hai điều trên ta suy ra được là sẽ tồn tại \(\hat{y}\) để cho phương trình \((10) < 0\) suy ra, \(\exists \hat{y}\) để cho phương trình (9) < 0, nên phương trình \((8)\) sẽ là một hàm non-convex (điều cần chứng minh).

Vậy ta đã chứng minh được phương trình \((7)\) là một hàm convex và phương trình \((8)\) là một hàm non-convex. Nếu các bạn muốn kiểm tra tính đúng đắn khi ta xây dựng hàm mất mát cho logistic regression là Cross-Entropy thì các bạn có thể đi tìm đạo hàm bậc hai theo \(\mathbf{w}\) của hàm Cross-Entropy và chứng minh nó \(\geq 0\). Mình sẽ  không đi chứng minh trong bài viết này, các bạn có thể thử sức.

4.5 Forward propagation

Từ phần này ta bắt đầu đi vào việc tính toán bên trong model. Forward propagation gọi là quá trình tính toán xuôi từ xuyên suốt từ input đến output.

Backpropagation logsitic regression

Ta có thể thấy ở hình trên các bộ trọng số \(\mathbf{w}\) sẽ được kết hợp với input sau đó đi qua một hàm kích hoạt (ở đây sẽ là hàm sigmoid) để cho ra output, và hồi quy logistic có thể coi là mạng neural đơn giản có một đơn vị neural.

https://projectsig.com/2017/08/11/logistic-regression-with-a-neural-network-cat-recognizer/

Thực ra ở phần trên mình đã tính output ở các phần trên, mình viết lại bên dưới:
\[
P = \frac{1}{1 + e^{-(\mathbf{w}^T\mathbf{x} + b)}}
\]
\(\mathbf{w}^T\mathbf{x} + b\) sẽ là input, hàm sigmoid kết hợp với input sẽ là model, kết quả P sẽ là output.

4.6 Backpropagation

Ngược với Forward propagation là Backpropagation, đây là quá trình tính toán ngược trong thuật toán. Ngược ở đây có nghĩa là chúng ta sẽ từ đi từ loss function để điều chỉnh bộ trọng số \(\mathbf{w}\) nhằm giảm được giá trị loss ở các lần tính toán xuôi tiếp theo, nhìn vào sơ đồ ta có thể thấy rõ hơn:

training logistic regression

Ta đã có hàm mất mát của logistic regression, lưu ý là mình đang xét với một điểm dữ liệu nên kí hiệu \(\sum_{i=1}^m\) đã bị bỏ đi:
\[
J(\mathbf{w}) = -(y^{(i)}\log{a^{(i)}} + (1 – y^{(i)})\log{(1 – a^{(i)}}))
\]
Ta có:
\[
\begin{align}
\frac{\partial{J(\mathbf{w})}}{\partial{\mathbf{w}}} =&-\left( y^{(i)}\frac{\mathbf{x}^{(i)}a^{(i)}(1-a^{(i)})}{a^{(i)}} + (1-y^{(i)})\frac{-\mathbf{x}^{(i)}a^{(i)}(1-a^{(i)})}{1-a^{(i)}} \right)\\
=& -(y^{(i)}\mathbf{x}^{(i)}(1-a^{(i)}) – \mathbf{x}^{(i)}a^{(i)}(1-y^{(i)})) \\
=& -(\mathbf{x}^{(i)}(y^{(i)}-a^{(i)}))\\
=& \mathbf{x}^{(i)}(a^{(i)}-y^{(i)})
\end{align}
\]
Vậy ta có công thức cập nhật cho \(\mathbf{w}\):
\[
\mathbf{w} = \mathbf{w} – \eta\frac{\partial{J(\mathbf{w})}}{\partial{\mathbf{w}}}= \mathbf{w} – \eta\mathbf{x}^{(i)}(a^{(i)}-y^{(i)})
\]

Nếu biểu diễn tổng quát cho toàn bộ dữ liệu ta có:
\[
\mathbf{w} = \mathbf{w} – \eta \frac{\mathbf{X}(\mathbf{A}-\mathbf{Y})^{T}}{m}
\]
Trong đó:
– \(\eta\): là tốc độ học
– \(y^{(i)}\): giá trị đúng của input \(\mathbf{x}^{(i)}\), \(y^{(i)}\) nhận giá trị \(0\) hoặc \(1\).
– \(a^{(i)}\): giá trị mô hình dự đoán ứng với input \(\mathbf{x}^{(i)}\).
– m: là số điểm dữ liệu.
– \(\mathbf{X}\): dạng biểu diễn tất cả điểm dữ liệu, ở phần kí hiệu mình đã chỉ rõ.
– \(\mathbf{A}\): dạng biểu diễn giá trị mô hình dự đoán được cho tất cả điểm dữ liệu.
– \(\mathbf{Y}\): dạng biểu diễn nhãn của tất cả điểm dữ liệu.

5. Tóm tắt thuật toán

Nếu bạn thấy các công thức toán bên trên khó hiểu hoặc đơn giản bạn chỉ muốn biết những thứ cơ bản về thuật toán logistic regression. Phần này mình sẽ tóm tắt những gì quan trọng nhất trong thuật toán logistic regression.

  • Hàm kích hoạt được sử dụng là hàm sigmoid:

    \[
    \sigma(x) = \frac{1}{1+e^{-x}}
    \]

  • Dạng model:
    \[
    P = \frac{1}{1 + e^{-(\mathbf{w}^T\mathbf{x} + b)}}
    \]

  • Hàm mất mát trên toàn bộ tập dữ liệu, chúng ta gọi đây là hàm Cross-Entropy:

    \[
    \mathcal{L}(\mathbf{w}) = -\sum_{i=1}^m(y^{(i)}\log{a^{(i)}} + (1 – y^{(i)})\log{(1 – a^{(i)}}))
    \]

  • Giá trị cập nhật cho bộ trọng số:
    \[
    \mathbf{w} = \mathbf{w} – \eta \frac{\mathbf{X}(\mathbf{A}-\mathbf{Y})^{T}}{m}
    \]

Trong đó:
– \(\eta\): là tốc độ học
– \(y^{(i)}\): giá trị đúng của input \(\mathbf{x}^{(i)}\), \(y^{(i)}\) nhận giá trị \(0\) hoặc \(1\).
– \(a^{(i)}\): giá trị mô hình dự đoán ứng với input \(\mathbf{x}^{(i)}\).
– m: là số điểm dữ liệu.
– \(\mathbf{X}\): dạng biểu diễn tất cả điểm dữ liệu, ở phần kí hiệu mình đã chỉ rõ.
– \(\mathbf{A}\): dạng biểu diễn giá trị mô hình dự đoán được cho tất cả điểm dữ liệu.
– \(\mathbf{Y}\): dạng biểu diễn nhãn của tất cả điểm dữ liệu.

6. Xây dựng thuật toán với code python

Phần này mình sẽ xây dựng thuật toán logistic regression để phân loại ảnh cats và dogs, mình sẽ gán nhãn cats là \(1\) và dogs là \(0\).

Trước khi đi vào phần code mình có một vài lưu ý:

  • Phần code mình viết chỉ đảm bảo là mô tả lại thuật toán, code mình chưa bắt exception nên muốn chạy đúng phải đảm bảo đúng định dạng input.

  • Phải đảm bảo data bạn sử dụng đã resize về đúng kích thước. ví dụ bạn để image_widght x image_height là \(128 * 128\) thì bạn phải đảm bảo dữ liệu của bạn đã đúng định dạng \(128 * 128\).

  • Config mình sẽ cấu hình trong file config.json

  • Nhãn dữ liệu là file label.json

  • Link github: https://github.com/trongnghia05/Deep-learning/tree/master/Logistic%20regression

6.1 Xây dựng hàm khởi tạo init_param()

Hàm này sẽ có nhiệm vụ khởi tạo bộ trọng số \(\mathbf{w}\) và tham số bias \(b\). Thông thường hai giá trị này sẽ có hai cách để khởi tạo, khởi tạo bằng \(0\) hoặc lấy giá trị ngẫu nhiên. Đối với Logistic regression cách khởi tạo bằng \(0\) sẽ hay được sử dụng:

"""
@author Trong Nghia

"""
def init_param(quantity_w,b=0, style ="zeros"):
    
    if(style=="random"):
        w = np.random.randn(quantity_w,1) * 0.01
    else:
        w = np.zeros(shape=(quantity_w,1))
    return w,b

6.2 Xây dựng hàm sigmoid()

"""
@author Trong Nghia

"""
def sigmoid(z):
    return 1 / (1 + np.exp(-z))

6.3 Xây dựng hàm foward_propagation()

Đây là quá trình tính toán Forward propagation:

"""
@author Trong Nghia

"""
def foward_propagation(w,b,X,Y):
    m = X.shape[1]
    A = sigmoid(np.dot(w.T, X) + b)
    cost = (- 1 / m) * np.sum(Y * np.log(A) + (1 - Y) * (np.log(1 - A)))
    return A,cost

6.4 Xây dựng hàm backpropagation()

Đây sẽ là quá trình tính đạo hàm \(w\) theo hàm mất mát:

"""
@author Trong Nghia

"""
def back_propagation(A,X,Y):
    m = X.shape[1]
    dw = (1 / m) * np.dot(X, (A - Y).T)
    db = (1 / m) * np.sum(A - Y)
    return dw,db

6.5 Xây dựng hàm training fit()

Hàm này sẽ nhận nhiệm vụ traning, sẽ có một vòng for để thực hiện quá trình này:

"""
@author Trong Nghia

"""
def fit(w, b, X, Y, epoch, learning_rate):
    costs = []
    arr_epoch = np.arange(1,epoch+1)
    for i in range(epoch):
        A, cost = foward_propagation(w, b, X, Y)
        dw, db = back_propagation(A, X, Y)
        w = w - learning_rate * dw
        b = b - learning_rate * db
        costs.append(cost)
        print("cost " + str(cost))
    return costs, arr_epoch, w

6.6 Xây dựng hàm dự đoán predict()

Hàm dự đoán này sẽ gần giống với hàm foward_propagation() chỉ khác ở chỗ mình sẽ xử lí output là nhãn của các ảnh test và số lượng ảnh là nhãn \(0\) và số lượng ảnh là nhãn \(1\) nếu bạn muốn custom lại kết quả output thì hãy thử làm việc đấy.

"""
@author Trong Nghia

"""
def predict(w, b, X):
    A = sigmoid(np.dot(w.T, X) + b)
    label_predict = np.zeros((1,A.shape[1]))
    num_label_1 = 0
    num_label_0 = 0
    for i in range(A.shape[1]):
        if(A[0][i] > 0.5):
            label_predict[0][i] = 1
            num_label_1 +=1
        elif(A[0][i] == 0.5):
            label_predict[0][i] = 0.5
        else:
            label_predict[0][i] = 0
            num_label_0 += 1
    return label_predict, num_label_1, num_label_0

6.7 Kết quả

Với epoch là \(10000\), learning rate là \(0.0015\) tuy giá trị loss khá thấp, độ chính xác trên tập train là khoảng \(98\)% nhưng mình thử với tập test toàn nhãn \(0\) thì chỉ được \(54\)% có nhiều lí do dẫn đến việc độ chính xác thấp như vậy trên tập test và đây còn gọi là hiện tượng overfitting về các vấn đề trong khi training mô hình mình sẽ viết trong một bài khác. Ở bài sau ta sẽ xây dựng một mạng neural và vẫn sử dụng bộ dữ liệu này để ta so sánh kết quả.

7. Tài liệu tham khảo

  1. https://blog.metaflow.fr/ml-notes-why-the-log-likelihood-24f7b6c40f83
  2. https://machinelearningcoban.com/2017/01/27/logisticregression Tác giả Vũ Hữu Tiệp

Rate this post

Viết một bình luận