ត្រឡប់ទៅបន្ទប់

ស្វែងយល់ពី Gradient Descent Algorithm

ស្វែងយល់ពីរ Algorithm ដែលជាមូលដ្ឋានគ្រឹះនៃ Machine Learning។ យល់ដឹងពីរបៀបដែលវាស្វែងរកតម្លៃអប្បបរមានៃអនុគមន៍ម្តងមួយជំហានៗ។

ចៅ ដារ៉ា - Founder of TFDevs

March 19, 2026

ធ្វើបច្ចុប្បន្នភាព: March 20, 2026

សង្ខេបការអាប់ដេត: បានបន្ថែមការអនុវត្ត Python និងការពន្យល់លម្អិតអំពី gradient descent។

ចែករំលែកអត្ថបទនេះ:

រូបភាពយកមកពី: Creating a Gradient Descent Animation in Python

Gradient Descent គឺជា optimization algorithm មូលដ្ឋានមួយ ក្នុងចំណោម algorithms ដែលមាននៅក្នុង machine learning។ វាជាវិធីសាស្រ្តសម្រាប់ស្វែងរកតម្លៃអប្បបរមានៃអនុគមន៏ ដោយដើរម្តងមួយជំហាន (iteration) ជាបន្តបន្ទាប់ក្នុងទិសដៅ ដែលធ្វើឲ្យអនុគមន៏កាន់តែតូចទៅៗ។

ប្រៀបធៀបលេងៗ

ស្រមៃថា អ្នកកំពុងឈរនៅលើភ្នំមួយដែលមានអ័ព្ទក្រាស់ ហើយអ្នកចង់ទៅជ្រលងខាងក្រោម។ អ្នកមិនអាចមើលឃើញឆ្ងាយទេដោយសារមានអ័ព្ទក្រាស់ពេក ប៉ុន្តែអ្នកនៅបាតជើងរបស់អ្នក អាចដឹងថាកំពុងចុះជ្រៅទៅៗ រឺ ឡើងខ្ពង់ទៅៗ តាមរយៈជម្រោលចោត ។ Gradient descent ធ្វើរការដូចគ្នានេះដែរ: វាធ្វើម្តងមួយជំហានតូចៗចុះក្រោម តាមផ្លូវចម្រោងបំផុត រហូតដល់វាទៅដល់ចំណុចអប្បបរមា ទាបបំផុត។

គណិតវិទ្យា

រូបមន្តមូលដ្ឋាន

Gradient descent ធ្វើបច្ចុប្បន្នភាព parameters ដោយប្រើរូបមន្តសាមញ្ញនេះ:

θnew=θoldαJ(θ)\theta_{new} = \theta_{old} - \alpha \nabla J(\theta)

ដែល:

  • θ\theta តំណាងឱ្យ parameters ដែលយើងកំពុង optimize (តើតម្លៃ Parameter ណាមួយដែលយើងកំពុងស្វែងរក ដែលធ្វើឲ្យអនុគមន៍ JJ មានតម្លៃតិចបំផុត)
  • α\alpha គឺ learning rate (អត្រាបោះជំហាន ឬ ទំហំជំហាន)
  • J(θ)J(\theta) គឺ cost functionobjective function ដែលយើងចង់ រកតម្លៃ θ\theta ណាដែលធ្វើឲ្យ JJ មានតម្លៃតូចបំផុត
  • J(θ)\nabla J(\theta) គឺ Gradient(ដេរីវេ | Derivative) នៃ JJ ជាអនុគមន៍នៃ θ\theta

ការយល់ដឹងពី Gradient: ពីសាមញ្ញទៅ កំរិតខ្ពស់

តោះបកស្រាយនិមិត្តសញ្ញា gradient \nabla (ហៅថា "nabla" ឬ "del") ដោយបង្កើតពីករណីសាមញ្ញបំផុត។

ករណី 1: អថេរតែមួយ (Parameter មួយ)

នៅពេលយើងមាន parameter តែមួយ, gradient គឺគ្រាន់តែជា ដេរីវេ:

J(θ)=dJdθ\nabla J(\theta) = \frac{dJ}{d\theta}

Derivative ប្រាប់យើងថា: "ប្រសិនបើខ្ញុំបង្កើន θ\theta បន្តិចបន្តួច តើ JJ ផ្លាស់ប្តូរប៉ុន្មាន?"

ឧទាហរណ៍: សម្រាប់ J(θ)=θ2J(\theta) = \theta^2:

J(θ)=dJdθ=2θ\nabla J(\theta) = \frac{dJ}{d\theta} = 2\theta
  • ប្រសិនបើ θ=5\theta = 5, នោះ J(5)=10\nabla J(5) = 10 → អនុគមន៍កំពុងកើនឡើង, ទៅខាងឆ្វេង (បន្ថយ θ\theta)
  • ប្រសិនបើ θ=3\theta = -3, នោះ J(3)=6\nabla J(-3) = -6 → អនុគមន៍កំពុងថយចុះ, ទៅខាងស្តាំ (បង្កើន θ\theta)
  • ប្រសិនបើ θ=0\theta = 0, នោះ J(0)=0\nabla J(0) = 0 → យើងស្ថិតនៅចំណុចអប្បបរមា!

ករណី 2: អថេរពីរ (Parameters ពីរ)

នៅពេលយើងមាន parameters ពីរ θ1\theta_1 និង θ2\theta_2, gradient ក្លាយជា vector មួយមានធាតុផ្សំពីរ:

J(θ1,θ2)=[Jθ1Jθ2]\nabla J(\theta_1, \theta_2) = \begin{bmatrix} \frac{\partial J}{\partial \theta_1} \\ \frac{\partial J}{\partial \theta_2} \end{bmatrix}

Partial derivative នីមួយៗ Jθi\frac{\partial J}{\partial \theta_i} សួរថា: "ប្រសិនបើខ្ញុំផ្លាស់ប្តូរតែ θi\theta_i (រក្សា អថេរផ្សេងទៀតថេរ), តើ JJ ផ្លាស់ប្តូរប៉ុន្មាន?"

ឧទាហរណ៍: សម្រាប់ J(θ1,θ2)=θ12+θ22J(\theta_1, \theta_2) = \theta_1^2 + \theta_2^2:

J=[2θ12θ2]\nabla J = \begin{bmatrix} 2\theta_1 \\ 2\theta_2 \end{bmatrix}

នៅចំណុច (θ1=3,θ2=4)(\theta_1=3, \theta_2=4):

J=[68]\nabla J = \begin{bmatrix} 6 \\ 8 \end{bmatrix}

Vector នេះចង្អុលទៅទិសនៃការឡើងចម្រោងបំផុត។ យើងទៅក្នុងទិសផ្ទុយ (ដក វា) ដើម្បីចុះក្រោម!

ករណី 3: អថេរច្រើន (ករណីទូទៅ)

សម្រាប់ n parameters θ1,θ2,,θn\theta_1, \theta_2, \ldots, \theta_n, gradient គឺ n-dimensional vector:

J(θ)=[Jθ1Jθ2Jθn]\nabla J(\theta) = \begin{bmatrix} \frac{\partial J}{\partial \theta_1} \\ \frac{\partial J}{\partial \theta_2} \\ \vdots \\ \frac{\partial J}{\partial \theta_n} \end{bmatrix}

ធាតុផ្សំនីមួយៗប្រាប់យើងថា តើ JJ ប្រែប្រួលប៉ុន្មាន ចំពោះការផ្លាស់ប្តូរនៃ parameter ក្នុងចំណោមណាមួយនោះ។ នេះគឺជាអ្វីដែលយើងត្រូវដឹង ដើម្បីកំណត់ថា តើយើងគួរកែ parameter នីមួយៗទៅទិសណា!

ចំណុចសំខាន់: មិនថាអ្នកមាន parameter 1 ឬ 1 លាន, គំនិតគឺដូចគ្នាតេ: គណនាថា តើ parameter នីមួយៗប៉ះពាល់ដល់ cost ប៉ុន្មាន, បន្ទាប់មកកែសម្រួលវាក្នុងទិសផ្ទុយ។

ឧទាហរណ៍ពេញលេញ

តោះមើល gradient descent ក្នុងការដំណើរការជាមួយករណីសាមញ្ញបំផុត: អថេរតែមួយ

សូមគិតរកការបន្ថយទៅប្រកដដែលអប្បបរមាសម្រាប់អនុគមន៍ quadratic:

J(θ)=θ2J(\theta) = \theta^2

Gradient (ដេរីវេ) គឺ:

J(θ)=dJdθ=2θ\nabla J(\theta) = \frac{dJ}{d\theta} = 2\theta

យើងអាចសរសេរ Gradient descent algorithm ជា:

θnew=θoldα2θold\theta_{new} = \theta_{old} - \alpha \cdot 2\theta_{old}

ចាប់ផ្ដើមនៅ θ0=10\theta_0 = 10 ជាមួយ learning rate α=0.1\alpha = 0.1:

Iteration 1 (ជំហានទី 1):

θ1=100.1×(2×10)=102=8\theta_1 = 10 - 0.1 \times (2 \times 10) = 10 - 2 = 8

Gradient វិជ្ជមាន (10 ជំរាលឡើងខាងលើ), ដូច្នេះយើងបានធ្វើចលនាទៅខាងឆ្វេង (បន្ថយ θ\theta)

Iteration 2 (ជំហានទី 2):

θ2=80.1×(2×8)=81.6=6.4\theta_2 = 8 - 0.1 \times (2 \times 8) = 8 - 1.6 = 6.4

នៅតែជា gradient វិជ្ជមាន, កំពុងតូចទៅ, ដូច្នេះជំហានតូចជាង

Iteration 3 (ជំហានទី 3):

θ3=6.40.1×(2×6.4)=6.41.28=5.12\theta_3 = 6.4 - 0.1 \times (2 \times 6.4) = 6.4 - 1.28 = 5.12

Pattern បន្ត: នៅពេលយើងចូលទៅកាន់ចំណុចអប្បបរមា, gradient កាន់តែតូចទៅៗ, ដូច្នេះជំហានរបស់យើងតូចជាងដោយស្វ័យប្រវត្តិ!

ជាមួយនឹងជំហាននីមួយៗ, យើងចូលទៅកាន់ជិតនូវចំណុចអប្បបរមានៅ θ=0\theta = 0។ សូមកត់សម្គាល់ថា ជំហានតូចជាងដោយធម្មជាតិ នៅពេល gradient ថយចុះក្បែរនូវចំណុចអប្បបរមា!

គំនិតសំខាន់ៗ

Learning Rate | អត្រាបោះជំហាន ឬ ទំហំជំហាន

Learning rate α\alpha មានសំខាន់សំខាន់:

  • ទំហំពេក: យើងអាចរំលងចំណុចអប្បបរមា ឬ បង្កើតការវិលជុំមិនចប់ (មិនដល់គោលដៅ)
  • ទំហំតូច: ចំណាយពេលច្រើនហើយ កម្រដល់គោលដៅ
  • សមស្រប: ទៅដល់គោលដៅបានយ៉ាងមានប្រសិទ្ធភាព

តោះធ្វើតេស្តជាមួយ learning rates ផ្សេងៗ ហើយមើលថាវាអាចប៉ះពាល់ដល់ការចូលរួមគ្នា (convergence) យ៉ាងដូចម្តេច!

សិក្សាអត្រាបោះជំហាន

0.0010.51.0
ណែនាំ: 0.100

ស្ថិតិ

ចំនួនដងធ្វើម្តងទៀត:0
ទីតាំង (x):5.0000
ការបាត់បង់:25.000000
ជម្រាល:10.0000

ការកំណត់រហ័ស

ខ្សែកោង

Loss (កាន់តែតូចមានន័យថា កំពុងខិតជិតអប្បបរមា)

អំពីអត្រាសិក្សា

ទាបពេក (< 0.05)

ការប្រមូលផ្តុំយឺតណាស់។ ក្បួនដោះស្រាយត្រូវការការធ្វើម្តងទៀតច្រើនដើម្បីឈានដល់អប្បបរមា ប៉ុន្តែផ្លូវមានស្ថេរភាព។

ល្អបំផុត (0.05 - 0.3)

តុល្យភាពល្អរវាងល្បឿននិងស្ថេរភាព។ ធ្វើឱ្យប្រមូលផ្តុំយ៉ាងមានប្រសិទ្ធភាពដោយមិនលើសពីអប្បបរមា។

ខ្ពស់ពេក (> 0.5)

អាចលើសពីអប្បបរមា ឬបែកខ្ញែក។ ក្បួនដោះស្រាយក្លាយជាមិនមានស្ថេរភាពហើយអាចនឹងមិនប្រមូលផ្តុំទេ។

ប្រភេទនៃ Gradient Descent

1. Batch Gradient Descent

ប្រើទិន្នន័យទាំងអស់ ដើម្បីគណនា gradient:

θ=θαθJ(θ)\theta = \theta - \alpha \nabla_\theta J(\theta)

ដែល J(θ)J(\theta) ត្រូវបានគណនាលើឧទាហរណ៍បន្តុបកយសិក្សាទាំងអស់។

2. Stochastic Gradient Descent (SGD)

Update parameters ដោយប្រើឧទាហរណ៍បន្តុបកយសិក្សាមួយម្តងមួយ ក្នុងមួយពេល:

θ=θαθJ(θ;x(i),y(i))\theta = \theta - \alpha \nabla_\theta J(\theta; x^{(i)}, y^{(i)})

3. Mini-batch Gradient Descent

ជាការប្រទាក់ចូលគ្នា: ប្រើbatch តូចមួយ នៃឧទាហរណ៍:

θ=θαθJ(θ;x(i:i+b),y(i:i+b))\theta = \theta - \alpha \nabla_\theta J(\theta; x^{(i:i+b)}, y^{(i:i+b)})

ដែល bb គឺ batch size។

ចំណុចរួមតូច (Convergence)

Gradient descent ចូលរួមគ្នា នៅពេល gradient ក្លាយជាតូចបំផុត:

J(θ)<ϵ|\nabla J(\theta)| < \epsilon

ដែល ϵ\epsilon គឺតម្លៃ threshold តូចមួយ។

បញ្ហាប្រឈម

  1. Local Minima: Algorithm អាចជាប់គាំងនៅ local minima ជំនួសឱ្យការស្វែងរក global minimum
  2. Saddle Points: ចំណុចដែល gradient រកឃើញថាសូន្យ ប៉ុន្តែមិនមែនជាចំណុចអប្បបរមា
  3. Plateau Regions: តំបន់ដែល gradient មានទំហំតូចបំផុត ធ្វើឱ្យការសិក្សាយឺត

ការអនុវត្តន៍ក្នុងពិភពលោកជាក់ស្តែង

Gradient descent ត្រូវបានប្រើដើម្បីបណ្តុះបណ្តាល:

  • Neural Networks: ការ Optimize parameters រាប់លាន
  • Linear Regression: ការស្វែងរក best-fit line
  • Logistic Regression: បញ្ហា classification
  • Support Vector Machines: ការស្វែងរក optimal hyperplanes

Gradient Descent ក្នុង Deep Learning

Deep Neural Network ប្រើ Gradient Descent ដើម្បីបណ្តុះបណ្តាលទម្ងន់ (weights) ក្នុង layers ផ្សេងៗ

រូបភាពខាងលើបង្ហាញពី Deep Neural Network — ប្រភេទ Neural Network ពេញនិយមមួយ ដែលប្រើ Gradient Descent ដើម្បី optimize cost function។

ក្នុង Deep Learning:

  • Input Layer ទទួល data (ឧ. pixels នៃរូបភាព, ពាក្យ, លេខ)
  • Hidden Layers ជ្រើរើសធ្វើ feature extraction — ស្វែងរកគំរូ (patterns) ស្មុគស្មាញ ពីទិន្នន័យ
  • Output Layer ផ្តល់ការទស្សន៍ទាយ (prediction) ចុងក្រោយ
  • Weights ww (ទម្ងន់) ក្នុង connections នីមួយៗ គឺជា parameters θ\theta ដែល Gradient Descent ត្រូវ optimize

ក្នុងអំឡុងពេល Training:

Forward PassCompute Loss J(θ)BackpropagationGradient Descent Update\begin{aligned} &\text{Forward Pass} \\ &\rightarrow \text{Compute Loss } J(\theta) \\ &\rightarrow \text{Backpropagation} \\ &\rightarrow \text{Gradient Descent Update} \end{aligned}

Network មួយ មាន neurons រាប់លាន → weights រាប់លាន → gradient vector មាន រាប់លាន dimensions — ប៉ុន្តែ Gradient Descent ដំណើរការដូចគ្នានឹង 1D ដែរ: update ក្នុងទិស opposite នៃ gradient!

អនុវត្តក្នុង Python

ខាងក្រោមជាការសរសេរកូដ Python ដោយមិនប្រើ ML libraries ណាមួយ។ Code block នីមួយៗ ត្រូវតទៅនឹងរូបមន្ត math ខាងលើ — ជួរ highlighted ជា formula ចម្បង។

ជំហានទី 1 — Cost Function និង Gradient

J(θ)=θ2,J(θ)=2θJ(\theta) = \theta^2, \qquad \nabla J(\theta) = 2\theta

gradient_descent.py
# J(θ) = θ²  →  អនុគមន៍ដែលយើងចង់ minimize
def cost(theta):
    return theta ** 2

# ∇J(θ) = dJ/dθ = 2θ  →  derivative (gradient) របស់វា
def gradient(theta):
    return 2 * theta

ជំហានទី 2 — Update Rule

θnew=θoldαJ(θ)\theta_{new} = \theta_{old} - \alpha \cdot \nabla J(\theta)

def update(theta, alpha):
    grad = gradient(theta)           # ① គណនា  ∇J(θ)
    return theta - alpha * grad      # ② អនុវត្ត  θ_new = θ_old − α·∇J(θ)

ជួរទី 3 គឺ formula update rule ខាងលើ សរសេរដោយផ្ទាល់ជា Python។

ជំហានទី 3 — Loop រហូតដល់ Convergence

Run updates រហូតដល់ J(θ)<ε|\nabla J(\theta)| < \varepsilon — នៅពេល gradient ស្ទើររកឃើញថាសូន្យ:

gradient_descent.py
def gradient_descent(theta_init, alpha, epsilon=1e-6, max_iters=1000):
    theta = theta_init                           # θ₀ — ចំណុចចាប់ផ្ដើម
    for i in range(max_iters):
        grad = gradient(theta)                   # ∇J(θ) = 2θ
        if abs(grad) < epsilon:                  # ឈប់: |∇J(θ)| < ε
            print(f"Converged at iteration {i}")
            break
        theta = theta - alpha * grad             # θ_new = θ_old − α·∇J(θ)
        if i < 5:
            print(f"  iter {i+1:2d}: θ={theta:.5f}  J={cost(theta):.5f}  ∇J={grad:.5f}")
    return theta
# ស្របតាម ការគណនា manual ខាងលើ: θ₀ = 10, α = 0.1
theta_min = gradient_descent(theta_init=10.0, alpha=0.1)
print(f"\nMinimum at θ = {theta_min:.8f}")

Output — ស្របតាម iterations manual ខាងលើ:

  iter  1: θ= 8.00000  J=64.00000  ∇J=20.00000
  iter  2: θ= 6.40000  J=40.96000  ∇J=16.00000
  iter  3: θ= 5.12000  J=26.21440  ∇J=12.80000
  iter  4: θ= 4.09600  J=16.77722  ∇J=10.24000
  iter  5: θ= 3.27680  J=10.73742  ∇J= 8.19200
Minimum at θ = 0.00000001

ជំហានទី 4 — Linear Regression: Parameters ពីរ

សម្រាប់ model y^=wX+b\hat{y} = wX + b, cost function ប្រើ mean squared error:

J(w,b)=1mi=1m(y^(i)y(i))2J(w, b) = \frac{1}{m} \sum_{i=1}^{m} \left(\hat{y}^{(i)} - y^{(i)}\right)^2

ជាមួយ partial derivatives:

Jw=2mi=1m(y^(i)y(i))x(i),Jb=2mi=1m(y^(i)y(i))\frac{\partial J}{\partial w} = \frac{2}{m} \sum_{i=1}^{m} \left(\hat{y}^{(i)} - y^{(i)}\right) x^{(i)}, \qquad \frac{\partial J}{\partial b} = \frac{2}{m} \sum_{i=1}^{m} \left(\hat{y}^{(i)} - y^{(i)}\right)

linear_regression_gd.py
import numpy as np

def linear_regression_gd(X, y, alpha=0.01, epochs=500):
    m = len(y)
    w, b = 0.0, 0.0                        # θ = [w, b] — initialize ទៅ zero
    for epoch in range(epochs):
        y_pred = w * X + b                 # forward pass:  ŷ = w·X + b
        error  = y_pred - y                # residuals:     ŷ − y
        dw = (2 / m) * np.dot(error, X)   # ∂J/∂w = (2/m) Σ (ŷ−y)·x
        db = (2 / m) * np.sum(error)       # ∂J/∂b = (2/m) Σ (ŷ−y)
        w = w - alpha * dw                 # w_new = w_old − α·∂J/∂w
        b = b - alpha * db                 # b_new = b_old − α·∂J/∂b
        if epoch % 100 == 0:
            loss = np.mean(error ** 2)     # J(w,b) = (1/m) Σ (ŷ−y)²
            print(f"Epoch {epoch:4d}: loss={loss:.4f}  w={w:.4f}  b={b:.4f}")
    return w, b

# y = 2·x  →  model គួរ converge ទៅ w≈2, b≈0
X = np.array([1.0, 2.0, 3.0, 4.0, 5.0])
y = np.array([2.0, 4.0, 6.0, 8.0, 10.0])
w, b = linear_regression_gd(X, y)
print(f"\nFitted:  ŷ = {w:.4f}·x + {b:.4f}")

ជួរ highlighted 7–12 ទំនាក់ទំនងដោយផ្ទាល់ទៅ formulas:

  • ជួរ 7–8: forward pass y^=wX+b\hat{y} = wX + b និង residuals
  • ជួរ 9–10: partial derivatives Jw\frac{\partial J}{\partial w} និង Jb\frac{\partial J}{\partial b}
  • ជួរ 11–12: gradient descent update rule θnew=θoldαJ\theta_{new} = \theta_{old} - \alpha \nabla J

ជំហានបន្ទាប់

នៅពេលអ្នកយល់ដឹង gradient descent, អ្នកអាចស្រាវជ្រាវ Algorithms បន្ថែមដូចជា:

  • Momentum: បន្ថែមល្បឿនទៅក្នុងការ update
  • Adam: Adaptive learning rates សម្រាប់ parameter នីមួយៗ
  • RMSprop: គ្រប់គ្រង sparse gradients បានល្អជាង