Danh sách bài viết

Bài 25: Đạo hàm (Derivative) trực quan — đo lường tốc độ thay đổi

Hiểu đạo hàm từ trực quan: slope của tangent line tại 1 điểm. Định nghĩa formal qua giới hạn, bảng đạo hàm cơ bản, quy tắc tổng / tích / thương / chain rule. Đạo hàm riêng, gradient, đạo hàm bậc 2. Đạo hàm sigmoid, ReLU. Numerical derivative bằng finite difference. Code Python ngắn.

24/05/2026
15 phút đọc
0 lượt xem
1

Mục tiêu bài học

Sau bài học, bạn sẽ:

  • Mô tả đạo hàm bằng 2 góc nhìn: tốc độ thay đổislope của tangent line.
  • Đọc được định nghĩa formal \( f'(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} \).
  • Tra được bảng đạo hàm cơ bản và áp dụng quy tắc tổng / tích / thương.
  • Áp dụng chain rule — nền tảng của backpropagation trong neural network.
  • Tính đạo hàm riêng \( \frac{\partial f}{\partial x} \) cho hàm nhiều biến và viết gradient \( \nabla f \).
  • Biết đạo hàm của sigmoid và ReLU — 2 activation hay gặp nhất trong DL.
  • Viết code Python tính numerical derivative bằng finite difference.

Bài này là cầu nối từ xác suất / thống kê (Bài 21–24) sang phần tối ưu hoá: Bài 26 (Loss function) và Bài 27 (Gradient Descent).

2

Vì sao AI cần đạo hàm

Mọi quá trình "training" trong ML / DL đều quy về một bài toán: tối thiểu hoá loss function. Loss là một con số đo "model sai bao nhiêu so với dữ liệu thật". Càng nhỏ càng tốt.

Câu hỏi đặt ra: với hàng triệu tham số (weight) trong model, làm sao biết phải điều chỉnh tham số nào theo hướng nào để loss giảm? Trả lời: tính đạo hàm của loss theo từng tham số. Đạo hàm cho biết:

  • Hướng nào thì loss tăng (dấu của đạo hàm).
  • Tốc độ loss thay đổi mỗi khi tham số thay đổi 1 đơn vị (độ lớn của đạo hàm).

Vector chứa toàn bộ các đạo hàm riêng đó gọi là gradient \( \nabla L \). Thuật toán gradient descent (Bài 27) đi ngược hướng gradient để giảm loss:

\[ \mathbf{w} \leftarrow \mathbf{w} - \eta \cdot \nabla L(\mathbf{w}) \]

Trong deep network, gradient của loss theo từng weight được tính qua thuật toán backpropagation — về bản chất chỉ là chain rule áp dụng đệ quy. Nắm chắc đạo hàm là điều kiện cần để hiểu mọi tài liệu DL về sau.

3

Đạo hàm — góc nhìn trực quan

Bắt đầu bằng ví dụ vật lý: bạn lái xe, vị trí theo thời gian là \( s(t) \). Vận tốc tại thời điểm \( t \) là tốc độ vị trí thay đổi — chính là đạo hàm \( s'(t) \). Nhìn vào kim đồng hồ tốc độ là bạn đang nhìn vào đạo hàm.

Tổng quát hoá: với một hàm \( f(x) \) bất kỳ, đạo hàm tại điểm \( x \) trả lời câu hỏi: nếu \( x \) thay đổi một lượng rất nhỏ, thì \( f(x) \) thay đổi nhanh hay chậm?

  • Đạo hàm dương: \( f \) đang tăng tại điểm đó.
  • Đạo hàm âm: \( f \) đang giảm.
  • Đạo hàm bằng 0: \( f \) phẳng — có thể là đỉnh, đáy, hoặc điểm yên ngựa.
  • Đạo hàm càng lớn (về trị tuyệt đối): \( f \) thay đổi càng nhanh.

Ví dụ với \( f(x) = x^2 \):

x y -1 0 1 2 slope tại x=0 là 0 (đáy) slope tại x=1 là 2 slope tại x=2 là 4

Càng đi sang phải, parabol càng dốc lên — đạo hàm tăng. Tại đáy \( x = 0 \), đường cong phẳng — đạo hàm bằng 0.

4

Định nghĩa formal qua giới hạn

Lấy 2 điểm gần nhau trên đồ thị: \( (x, f(x)) \) và \( (x+h, f(x+h)) \). Slope của cát tuyến (secant) nối 2 điểm đó là:

\[ \frac{f(x+h) - f(x)}{h} \]

Cho \( h \) tiến tới 0, cát tuyến biến thành tiếp tuyến (tangent). Slope tiếp tuyến đó chính là đạo hàm:

\[ f'(x) = \frac{df}{dx} = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} \]

Ba ký hiệu cùng nghĩa, mỗi cái xuất phát từ một truyền thống:

  • \( f'(x) \) — ký hiệu Lagrange, gọn, hay dùng trong tài liệu phổ thông.
  • \( \frac{df}{dx} \) — ký hiệu Leibniz, làm rõ "biến nào theo biến nào". Tiện cho chain rule.
  • \( Df \) hoặc \( \partial_x f \) — ký hiệu vận hành (operator), hay gặp trong giải tích bậc cao.

Ví dụ tính bằng định nghĩa với \( f(x) = x^2 \):

\[ f'(x) = \lim_{h \to 0} \frac{(x+h)^2 - x^2}{h} = \lim_{h \to 0} \frac{2xh + h^2}{h} = \lim_{h \to 0} (2x + h) = 2x \]

Vậy \( (x^2)' = 2x \). Tại \( x = 3 \), đạo hàm là 6. Khớp với hình ảnh "parabol càng đi sang phải càng dốc" ở mục 3.

5

Ý nghĩa hình học — slope của tangent line

Đạo hàm \( f'(a) \) là hệ số góc của tiếp tuyến với đồ thị tại điểm \( x = a \). Phương trình tiếp tuyến tại \( (a, f(a)) \):

\[ y = f(a) + f'(a) \cdot (x - a) \]

Đây cũng là xấp xỉ tuyến tính tốt nhất của hàm \( f \) quanh điểm \( a \). Khi \( x \) gần \( a \), ta có:

\[ f(x) \approx f(a) + f'(a) \cdot (x - a) \]

Ý tưởng "xấp xỉ tuyến tính quanh một điểm" là nền cho:

  • Gradient descent: tại mỗi bước, đi theo hướng mà loss giảm tuyến tính nhanh nhất — chính là ngược hướng gradient.
  • Newton's method tìm nghiệm: dùng tiếp tuyến để lặp về điểm cắt trục \( x \).
  • Taylor expansion (mở rộng lên đạo hàm bậc cao): xấp xỉ hàm bằng đa thức.
6

Bảng đạo hàm cơ bản

Một số công thức cần thuộc — đủ để tính tay 90% bài toán mà bạn gặp khi đọc tài liệu ML / DL. Không cần chứng minh ở giai đoạn này.

  • Hằng số: \( (c)' = 0 \).
  • Hàm đồng nhất: \( (x)' = 1 \).
  • Luỹ thừa: \( (x^n)' = n \, x^{n-1} \) — đúng cho mọi \( n \in \mathbb{R} \) (kể cả âm và phân số).
  • Mũ tự nhiên: \( (e^x)' = e^x \) — hàm duy nhất bằng đạo hàm của chính nó.
  • Mũ tổng quát: \( (a^x)' = a^x \ln a \).
  • Logarit tự nhiên: \( (\ln x)' = \frac{1}{x} \) (với \( x > 0 \)).
  • Sin / cos: \( (\sin x)' = \cos x \); \( (\cos x)' = -\sin x \).
  • Tang: \( (\tan x)' = \frac{1}{\cos^2 x} = 1 + \tan^2 x \).

Vài ví dụ áp dụng nhanh:

  • \( f(x) = x^3 \Rightarrow f'(x) = 3x^2 \).
  • \( f(x) = \sqrt{x} = x^{1/2} \Rightarrow f'(x) = \frac{1}{2} x^{-1/2} = \frac{1}{2\sqrt{x}} \).
  • \( f(x) = \frac{1}{x} = x^{-1} \Rightarrow f'(x) = -x^{-2} = -\frac{1}{x^2} \).
7

Quy tắc tính đạo hàm

Kết hợp 4 quy tắc dưới với bảng cơ bản, bạn tính được đạo hàm của hầu hết biểu thức cổ điển.

Quy tắc tổng

\[ (f + g)'(x) = f'(x) + g'(x) \]

Ví dụ: \( (3x^2 + 2x + 1)' = 6x + 2 + 0 = 6x + 2 \). Hằng số nhân vào hàm thì đưa ra ngoài: \( (c \, f)' = c \, f' \).

Quy tắc tích

\[ (f \, g)'(x) = f'(x) \, g(x) + f(x) \, g'(x) \]

Đọc nôm na: "đạo hàm cái thứ nhất nhân nguyên cái thứ hai, cộng nguyên cái thứ nhất nhân đạo hàm cái thứ hai". Ví dụ với \( f(x) = x^2 \, e^x \):

\[ f'(x) = 2x \cdot e^x + x^2 \cdot e^x = e^x (x^2 + 2x) \]

Quy tắc thương

\[ \left( \frac{f}{g} \right)'(x) = \frac{f'(x) \, g(x) - f(x) \, g'(x)}{g(x)^2} \]

Ví dụ với \( f(x) = \frac{x}{x^2 + 1} \):

\[ f'(x) = \frac{1 \cdot (x^2 + 1) - x \cdot 2x}{(x^2 + 1)^2} = \frac{1 - x^2}{(x^2 + 1)^2} \]

Quy tắc hàm hợp

Đó là chain rule — mục riêng bên dưới vì quan trọng nhất.

8

Chain rule — viên gạch của backpropagation

Nếu \( y = f(g(x)) \) là hàm hợp, đạo hàm theo \( x \) bằng "đạo hàm ngoài nhân đạo hàm trong":

\[ \big( f(g(x)) \big)' = f'(g(x)) \cdot g'(x) \]

Dạng Leibniz dễ nhớ hơn — đặt \( u = g(x) \) thì \( y = f(u) \):

\[ \frac{dy}{dx} = \frac{dy}{du} \cdot \frac{du}{dx} \]

Trông như "rút gọn" \( du \). Đó cũng là lý do ký hiệu Leibniz tiện trong giải tích.

Ví dụ với \( f(x) = (x^2 + 1)^3 \):

  • Hàm ngoài: \( u^3 \), đạo hàm theo \( u \) là \( 3u^2 \).
  • Hàm trong: \( u = x^2 + 1 \), đạo hàm theo \( x \) là \( 2x \).
  • Kết quả: \( f'(x) = 3(x^2 + 1)^2 \cdot 2x = 6x(x^2 + 1)^2 \).

Chain rule mở rộng cho nhiều tầng. Với \( y = f(g(h(x))) \):

\[ \frac{dy}{dx} = f'(g(h(x))) \cdot g'(h(x)) \cdot h'(x) \]

Liên hệ với backpropagation: một neural network sâu chính là hàm hợp lồng nhiều tầng. Ví dụ network 3 lớp:

\[ \hat{y} = f_3(f_2(f_1(\mathbf{x}))) \]

Loss \( L \) là một hàm của \( \hat{y} \). Để tính \( \frac{\partial L}{\partial \mathbf{w}_1} \) (gradient theo weight ở lớp đầu), ta áp chain rule ngược từ output về input — đó chính là backpropagation. Mỗi lớp đóng góp một thừa số cho tích.

9

Đạo hàm riêng (partial derivative)

Trong ML, hàm gần như luôn nhận nhiều biến — loss phụ thuộc hàng triệu weight. Khi hàm \( f(x_1, x_2, \ldots, x_n) \) có nhiều biến, ta cần biết loss thay đổi thế nào khi một biến thay đổi, các biến còn lại giữ nguyên. Đó là đạo hàm riêng.

Ký hiệu (chữ \( \partial \) — "partial", thay cho \( d \) trong đạo hàm thường):

\[ \frac{\partial f}{\partial x_i} \]

Cách tính rất đơn giản: coi tất cả các biến khác là hằng số, rồi đạo hàm như hàm 1 biến.

Ví dụ với \( f(x, y) = x^2 + xy + 3y^2 \):

  • Đạo hàm theo \( x \) (coi \( y \) là hằng số): \[ \frac{\partial f}{\partial x} = 2x + y + 0 = 2x + y \]
  • Đạo hàm theo \( y \) (coi \( x \) là hằng số): \[ \frac{\partial f}{\partial y} = 0 + x + 6y = x + 6y \]

Ý nghĩa: tại điểm \( (x, y) = (1, 2) \), nếu cho \( x \) tăng 1 chút (giữ \( y = 2 \)), \( f \) tăng theo tỉ lệ \( 2(1) + 2 = 4 \). Nếu cho \( y \) tăng 1 chút (giữ \( x = 1 \)), \( f \) tăng theo tỉ lệ \( 1 + 6(2) = 13 \). Biến \( y \) "có ảnh hưởng lớn hơn" tại điểm đó.

10

Gradient — vector các đạo hàm riêng

Gom tất cả đạo hàm riêng của hàm nhiều biến \( f(x_1, \ldots, x_n) \) lại thành một vector, ta được gradient:

\[ \nabla f = \left( \frac{\partial f}{\partial x_1}, \; \frac{\partial f}{\partial x_2}, \; \ldots, \; \frac{\partial f}{\partial x_n} \right) \]

Ký hiệu \( \nabla \) đọc là "nabla". Gradient là một vector \( n \) chiều (xem lại Bài 18).

Tính chất quan trọng của gradient:

  • Tại mỗi điểm, \( \nabla f \) chỉ về hướng \( f \) tăng nhanh nhất.
  • Ngược lại, \( -\nabla f \) chỉ về hướng \( f \) giảm nhanh nhất.
  • Độ lớn \( \|\nabla f\| \) cho biết tốc độ thay đổi tối đa tại điểm đó.
  • Tại điểm cực trị (min / max / yên ngựa), \( \nabla f = \mathbf{0} \).

Hai tính chất đầu là lý do gradient descent đi theo hướng \( -\nabla L \) để giảm loss. Bài 27 sẽ đi chi tiết. Trong PyTorch / TensorFlow, gradient được tính tự động qua autograd dựa trên chain rule — bạn viết forward pass, framework lo phần đạo hàm.

Ví dụ với \( f(x, y) = x^2 + 3y^2 \), tại điểm \( (1, 2) \):

\[ \nabla f(1, 2) = (2x, \; 6y)\big|_{(1,2)} = (2, \; 12) \]

Hướng tăng nhanh nhất của \( f \) tại đó là theo vector \( (2, 12) \); hướng giảm nhanh nhất là \( (-2, -12) \).

11

Đạo hàm bậc 2 — preview

Đạo hàm của \( f'(x) \) gọi là đạo hàm bậc 2, ký hiệu \( f''(x) \) hoặc \( \frac{d^2 f}{dx^2} \). Ý nghĩa:

  • \( f''(x) > 0 \): đồ thị lõm lên (concave up) — như parabol mở lên. Đạo hàm thứ nhất đang tăng.
  • \( f''(x) < 0 \): lõm xuống (concave down) — như parabol mở xuống.
  • \( f''(x) = 0 \): điểm uốn (inflection point).

Trong tối ưu hoá:

  • Tại điểm cực trị (\( f'(x_0) = 0 \)), nếu \( f''(x_0) > 0 \) thì \( x_0 \) là cực tiểu địa phương; nếu \( f''(x_0) < 0 \) thì là cực đại.
  • Với hàm nhiều biến, đạo hàm bậc 2 được gom thành ma trận Hessian \( H \). Optimizer bậc 2 (Newton) dùng \( H \) để hội tụ nhanh hơn nhưng đắt — DL thường tránh, dùng các xấp xỉ như L-BFGS hoặc các optimizer adaptive (Adam, RMSProp).

Bài này chỉ dừng ở preview. Đại đa số bài toán DL chỉ cần đạo hàm bậc 1.

12

Đạo hàm của sigmoid và ReLU

Hai activation function quen thuộc trong neural network. Backpropagation cần đạo hàm của chúng.

Sigmoid

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

Sigmoid nén mọi đầu vào về khoảng \( (0, 1) \), dùng cho output của bài toán phân loại nhị phân. Đạo hàm có dạng đẹp:

\[ \sigma'(x) = \sigma(x) \big( 1 - \sigma(x) \big) \]

Nghĩa là, nếu đã tính được \( \sigma(x) \), thì đạo hàm chỉ là một phép nhân — implementation tiết kiệm. Lưu ý: khi \( |x| \) lớn, \( \sigma(x) \) tiến về 0 hoặc 1, làm \( \sigma'(x) \to 0 \). Đây là nguồn gốc của vanishing gradient ở các network sâu dùng sigmoid.

ReLU

\[ \text{ReLU}(x) = \max(0, x) = \begin{cases} x & \text{nếu } x > 0 \\ 0 & \text{nếu } x \le 0 \end{cases} \]

Đạo hàm:

\[ \text{ReLU}'(x) = \begin{cases} 1 & \text{nếu } x > 0 \\ 0 & \text{nếu } x < 0 \end{cases} \]

Tại \( x = 0 \) đạo hàm không xác định theo nghĩa cổ điển; trong thực tế các framework quy ước \( \text{ReLU}'(0) = 0 \) (PyTorch, TensorFlow) — không ảnh hưởng training. Ưu điểm: tính nhanh, không bị vanishing gradient ở phần dương. Nhược điểm: nếu một neuron luôn nhận đầu vào âm, gradient luôn 0 → "dying ReLU".

13

Numerical derivative — finite difference

Đôi khi không có (hoặc không tiện viết) công thức analytic của \( f \) — ví dụ \( f \) là kết quả của một simulation. Khi đó ta xấp xỉ đạo hàm bằng finite difference.

Forward difference:

\[ f'(x) \approx \frac{f(x + h) - f(x)}{h} \]

Đây chính là biểu thức bên trong giới hạn ở mục 4, nhưng dừng ở \( h \) nhỏ hữu hạn thay vì cho \( h \to 0 \). Sai số tỉ lệ với \( h \).

Central difference (đối xứng):

\[ f'(x) \approx \frac{f(x + h) - f(x - h)}{2h} \]

Sai số tỉ lệ với \( h^2 \) — chính xác hơn forward difference cho cùng một \( h \). Đây là công thức mặc định cho gradient checking trong DL.

Chọn \( h \) thế nào? Quá lớn thì xấp xỉ kém; quá nhỏ thì sai số làm tròn float (machine epsilon ~ \( 10^{-16} \) cho float64) chiếm ưu thế. Giá trị hay dùng cho float64: \( h \approx 10^{-5} \) đến \( 10^{-7} \).

Trong training thật, finite difference không dùng để tính gradient — quá chậm khi có hàng triệu tham số. Thay vào đó, framework dùng automatic differentiation (autograd) — chính xác đến machine precision và nhanh tương đương forward pass. Finite difference chủ yếu dùng để kiểm tra gradient (gradient check) khi viết layer custom.

14

Code Python

Tính numerical derivative của \( f(x) = x^2 \) tại \( x = 3 \) và so sánh với đáp án analytic \( f'(3) = 6 \).

import math


def numerical_derivative(f, x, h=1e-5):
    """Central difference: chính xác đến O(h^2)."""
    return (f(x + h) - f(x - h)) / (2 * h)


def f(x):
    return x ** 2


# So sánh tại x = 3 với nhiều giá trị h
for h in [1e-1, 1e-3, 1e-5, 1e-7, 1e-9, 1e-12]:
    approx = numerical_derivative(f, 3, h)
    print(f"h = {h:.0e}  ->  f'(3) ~ {approx:.10f}  (analytic = 6)")


# Sigmoid và đạo hàm
def sigmoid(x):
    return 1 / (1 + math.exp(-x))


def sigmoid_derivative_analytic(x):
    s = sigmoid(x)
    return s * (1 - s)


x0 = 0.5
print()
print(f"sigmoid'(0.5) analytic   = {sigmoid_derivative_analytic(x0):.6f}")
print(f"sigmoid'(0.5) numerical  = {numerical_derivative(sigmoid, x0):.6f}")

Output (tóm tắt):

h = 1e-01  ->  f'(3) ~ 6.0000000000  (analytic = 6)
h = 1e-03  ->  f'(3) ~ 6.0000000000
h = 1e-05  ->  f'(3) ~ 6.0000000000
h = 1e-07  ->  f'(3) ~ 5.9999999893
h = 1e-09  ->  f'(3) ~ 6.0000004137
h = 1e-12  ->  f'(3) ~ 6.0005334035

sigmoid'(0.5) analytic   = 0.235004
sigmoid'(0.5) numerical  = 0.235004

Quan sát đáng nhớ:

  • Với \( f(x) = x^2 \), \( h = 10^{-5} \) cho kết quả gần như chính xác.
  • Khi \( h \) quá nhỏ (\( 10^{-12} \)), sai số làm tròn float64 chiếm ưu thế — kết quả tệ hơn cả \( h = 10^{-3} \). Đây là lý do không nên đặt \( h \) "càng nhỏ càng tốt".
  • Sigmoid analytic và numerical khớp tới 6 chữ số — đủ cho gradient checking.
15

Bài tập

  1. Tính đạo hàm của \( f(x) = 3x^2 + 2x + 1 \). Tính giá trị tại \( x = 2 \).
  2. Áp dụng chain rule tính đạo hàm của \( f(x) = (x^2 + 1)^3 \) và của \( g(x) = e^{-x^2} \).
  3. Cho \( f(x, y) = x^2 y + \sin(y) \). Tính \( \frac{\partial f}{\partial x} \), \( \frac{\partial f}{\partial y} \), và viết \( \nabla f \) tại điểm \( (1, 0) \).
  4. Viết hàm numerical_derivative và dùng để kiểm tra đạo hàm của \( f(x) = \ln(x) \) tại \( x = 2 \) (analytic \( = 1/2 \)).
  5. Chứng minh \( \sigma'(x) = \sigma(x)(1 - \sigma(x)) \) bằng cách lấy đạo hàm của \( \sigma(x) = (1 + e^{-x})^{-1} \) bằng chain rule.
Đáp án ngắn
  1. \( f'(x) = 6x + 2 \); \( f'(2) = 14 \).
  2. \( (x^2 + 1)^3 \): hàm ngoài \( u^3 \to 3u^2 \), hàm trong \( 2x \), kết quả \( 6x(x^2+1)^2 \). Với \( e^{-x^2} \): hàm ngoài \( e^u \to e^u \), hàm trong \( -2x \), kết quả \( -2x \, e^{-x^2} \).
  3. \( \frac{\partial f}{\partial x} = 2xy \); \( \frac{\partial f}{\partial y} = x^2 + \cos(y) \). Tại \( (1, 0) \): \( \nabla f = (0, \; 1 + 1) = (0, \; 2) \).
  4. Numerical với \( h = 10^{-5} \) cho ~0.5000000000, khớp analytic \( 1/2 \).
  5. Đặt \( u = 1 + e^{-x} \), \( \sigma = u^{-1} \). \( \sigma' = -u^{-2} \cdot u' = -u^{-2} \cdot (-e^{-x}) = \frac{e^{-x}}{(1+e^{-x})^2} \). Viết lại: \( \frac{e^{-x}}{1+e^{-x}} \cdot \frac{1}{1+e^{-x}} = (1 - \sigma) \cdot \sigma \). Xong.
16

Tóm tắt

  • Đạo hàm \( f'(x) = \lim_{h \to 0} \frac{f(x+h) - f(x)}{h} \) đo tốc độ thay đổi của \( f \) tại điểm \( x \).
  • Hình học: \( f'(x) \) là slope của tiếp tuyến tại \( (x, f(x)) \).
  • Bảng cơ bản: \( (c)' = 0 \), \( (x^n)' = nx^{n-1} \), \( (e^x)' = e^x \), \( (\ln x)' = 1/x \), \( (\sin x)' = \cos x \), \( (\cos x)' = -\sin x \).
  • Quy tắc: tổng \( (f+g)' = f' + g' \); tích \( (fg)' = f'g + fg' \); thương \( (f/g)' = (f'g - fg')/g^2 \).
  • Chain rule \( (f(g(x)))' = f'(g(x)) \cdot g'(x) \) — nền của backpropagation.
  • Đạo hàm riêng \( \frac{\partial f}{\partial x_i} \): coi các biến khác là hằng số, đạo hàm 1 biến.
  • Gradient \( \nabla f \) là vector các đạo hàm riêng, chỉ về hướng \( f \) tăng nhanh nhất.
  • Sigmoid: \( \sigma'(x) = \sigma(x)(1 - \sigma(x)) \). ReLU: \( \text{ReLU}'(x) = 1 \) nếu \( x > 0 \), \( 0 \) ngược lại.
  • Numerical derivative bằng central difference: \( f'(x) \approx \frac{f(x+h) - f(x-h)}{2h} \) với \( h \approx 10^{-5} \). Dùng để kiểm tra, không dùng để training.