0

Nhập môn Reinforcement Learning: Continuous Control và Thuật toán REINFORCE (Policy Gradient)

Nhập môn Reinforcement Learning: Continuous Control và Thuật toán REINFORCE (Policy Gradient)

Chào mọi người, quay trở lại với series RL. Ở các tập trước, chúng ta đã tung hoành với các thuật toán Tabular như Q-Learning hay SARSA. Nhưng hãy nhìn lại xem, chúng ta giải quyết được những gì? Bài toán Gridworld (đi lên, xuống, trái, phải), bài toán Multi-armed Bandit (chọn 1 trong K cánh tay). Điểm chung của chúng là gì? Đó là Discrete Action Space (Không gian hành động rời rạc).

Nhưng cuộc đời không chỉ có việc ấn nút A hay nút B. Giả sử bạn đang điều khiển một con robot hình người (Humanoid) hoặc một chiếc xe tự lái. Bạn không thể bảo xe "rẽ trái" hay "rẽ phải" một cách chung chung được. Bạn phải điều khiển một Continuous Action Space (Không gian hành động liên tục): góc bẻ lái vô lăng là 12.5 độ, lực đạp chân ga là 45.2%, lực phanh là 0%. Số lượng hành động lúc này là vô hạn (infinite).

Nếu dùng Q-Learning, để chọn được action tốt nhất, bạn phải làm phép toán maxaQ(s,a)\max_a Q(s, a). Nhưng làm sao bạn có thể tìm giá trị max trong một không gian liên tục (continuous) mà không giải một bài toán tối ưu hóa (optimization problem) cực kỳ cồng kềnh ở MỖI STEP?

Đó là lúc chúng ta phải từ bỏ việc học Value Function để gián tiếp suy ra Policy. Thay vào đó, chúng ta sẽ học trực tiếp một policy function. Phương pháp này gọi là Policy Gradient. Hôm nay, chúng ta sẽ đi vào nền tảng của nó: Thuật toán REINFORCE.


1. Parameterized Policy (Tham số hóa Policy)

Thay vì dùng một cái bảng (hoặc một Neural Network) để ước lượng Q(s,a)Q(s, a) rồi mới suy ra cách đi, Policy Gradient sẽ ném thẳng State ss vào một hàm (có thể là Neural Network) và output trực tiếp ra Policy.

Policy bây giờ sẽ có tham số θ\theta (đọc là theta, chính là các weights của Neural Network), ký hiệu là πθ(as)\pi_\theta(a|s). Mục tiêu của chúng ta là tìm bộ θ\theta sao cho Expected Return (Kỳ vọng phần thưởng tổng cộng) là lớn nhất.

1.1 Discrete Action (Softmax Policy)

Nếu không gian là rời rạc (như game Atari), NN sẽ output ra một vector các giá trị (gọi là numerical preferences h(s,a,θ)h(s,a,\theta)). Sau đó ta đưa qua hàm Softmax để ép nó thành xác suất (từ 0 đến 1, tổng bằng 1). Agent sẽ dựa vào xác suất này để tung xúc xắc chọn action.

πθ(as)=eh(s,a,θ)beh(s,b,θ)\pi_\theta(a|s) = \frac{e^{h(s, a, \theta)}}{\sum_b e^{h(s, b, \theta)}}

1.2 Continuous Action (Gaussian Policy)

Đây mới là cái ăn tiền! Nếu action là một số thực liên tục, ta không thể dùng Softmax được nữa. Thay vào đó, ta ép Policy tuân theo một Gaussian distribution (Phân phối chuẩn - Hình quả chuông).

Neural Network sẽ nhận input là State ss, và output ra 2 giá trị:

  1. Mean (Giá trị trung bình - μ\mu): Tượng trưng cho hành động "tốt nhất" (ví dụ: bẻ lái 15 độ).
  2. Variance (Phương sai - σ2\sigma^2): Tượng trưng cho mức độ "tự tin" của model. (Phương sai lớn = explore nhiều, phương sai nhỏ = tự tin, chỉ chọn sát giá trị μ\mu).

πθ(as)=1σ2πexp((aμ)22σ2)\pi_\theta(a|s) = \frac{1}{\sigma \sqrt{2\pi}} \exp \left( -\frac{(a - \mu)^2}{2\sigma^2} \right)

Khi đó, để chọn action, Agent chỉ việc lấy mẫu (sample) từ phân phối Gaussian này: aN(μ,σ2)a \sim \mathcal{N}(\mu, \sigma^2). Vậy là ta đã giải quyết xong bài toán chọn hành động trong không gian liên tục một cách vô cùng thanh lịch!


2. Policy Gradient Theorem và Log-Derivative Trick

Mục tiêu của chúng ta là tối đa hóa Expected Return, gọi là J(θ)J(\theta). Để tối đa hóa nó, ta dùng Gradient Ascent (Tăng dần theo đạo hàm):

θt+1=θt+αθJ(θt)\theta_{t+1} = \theta_t + \alpha \nabla_\theta J(\theta_t)

Trong đó, θJ(θ)\nabla_\theta J(\theta) là gradient (đạo hàm) của objective function theo bộ tham số θ\theta. Nhưng làm sao để tính được cái đạo hàm này? Nó phụ thuộc vào việc Agent tương tác với môi trường, mà môi trường thì ta lại không biết trước (Unknown Dynamics).

Giới nghiên cứu RL đã chứng minh được một định lý vĩ đại gọi là Policy Gradient Theorem:

θJ(θ)sdπ(s)aqπ(s,a)θπθ(as)\nabla_\theta J(\theta) \propto \sum_s d^\pi(s) \sum_a q_\pi(s, a) \nabla_\theta \pi_\theta(a|s)

(Với dπ(s)d^\pi(s) là phân phối trạng thái - xác suất ta đứng ở state ss).

Công thức này đẹp, nhưng vẫn không dùng trực tiếp được vì có quá nhiều dấu \sum. Ở đây, ta áp dụng một phép biến đổi toán học kinh điển gọi là Log-Derivative Trick (hoặc Score-Function Trick). Dựa vào tính chất đạo hàm của hàm logarit: lnx=xx\nabla \ln x = \frac{\nabla x}{x}, ta có:

θπθ(as)=πθ(as)θlnπθ(as)\nabla_\theta \pi_\theta(a|s) = \pi_\theta(a|s) \nabla_\theta \ln \pi_\theta(a|s)

Thế nó ngược lại vào Policy Gradient Theorem, ta thu được dạng Kỳ vọng (Expectation):

θJ(θ)Eπ[qπ(s,a)θlnπθ(as)]\nabla_\theta J(\theta) \propto \mathbb{E}_{\pi} \left[ q_\pi(s, a) \nabla_\theta \ln \pi_\theta(a|s) \right]

Tuyệt vời! Dấu E\mathbb{E} (Kỳ vọng) có nghĩa là ta có thể Sample (lấy mẫu ngẫu nhiên từ thực tế) để xấp xỉ nó. Không cần biết môi trường hoạt động ra sao, chỉ cần Agent cứ đi, nhận kết quả, rồi nhét vào công thức là được.


3. Thuật toán REINFORCE (Monte Carlo Policy Gradient)

Thuật toán REINFORCE sử dụng chính kết quả từ Policy Gradient Theorem. Nhưng trong công thức có cái qπ(s,a)q_\pi(s, a) (giá trị thực sự của action đó). Vì ta đang làm Policy-based chứ không phải Value-based, ta không có sẵn bảng Q-Table nào cả.

Giải pháp của REINFORCE cực kỳ "cục súc" (đúng chuẩn Monte Carlo): Cứ cho Agent chơi hết một ván (một episode). Tới cuối game, ta tính được tổng Return thực tế GtG_t cho từng step. Và ta lấy luôn GtG_t này thay cho qπ(s,a)q_\pi(s, a)!

Công thức update trọng số θ\theta của REINFORCE:

θt+1θt+αGtθlnπθ(AtSt)\theta_{t+1} \leftarrow \theta_t + \alpha G_t \nabla_\theta \ln \pi_\theta(A_t|S_t)

3.1 Giải thích công thức một cách "con người"

Hãy bóc tách cái công thức update thần thánh này ra:

  1. θlnπθ(AtSt)\nabla_\theta \ln \pi_\theta(A_t|S_t): Đây là hướng (direction) trong không gian tham số. Nếu ta cộng cái này vào θ\theta, xác suất chọn action AtA_t tại state StS_t sẽ tăng lên.
  2. GtG_t (Return thực tế): Đóng vai trò là cái loa phóng thanh (scalar multiplier).
    • Nếu Agent nhận được GtG_t dương và rất to (Action tốt): Hướng gradient được khuếch đại \rightarrow Policy sẽ được update mạnh tay để chọn action đó nhiều hơn trong tương lai.
    • Nếu GtG_t âm (Action ngu): Hướng gradient bị đổi ngược lại \rightarrow Policy sẽ né action đó ra ở các lần sau.

Đúng như cái tên của nó: Tăng cường (REINFORCE) những hành động mang lại kết quả tốt.

3.2 Pseudocode (Mã giả) của REINFORCE

Khởi tạo policy network π(a|s, θ) với bộ weights θ ngẫu nhiên.
Khởi tạo learning rate α.

Lặp cho mỗi episode:
    // 1. Collect Data (Dùng Monte Carlo)
    Dùng policy hiện tại π_θ để chơi hết 1 ván game, thu thập quỹ đạo (trajectory):
    S_0, A_0, R_1, S_1, A_1, R_2, ..., S_{T-1}, A_{T-1}, R_T
    
    // 2. Cập nhật Policy
    Lặp với mỗi time step t = 0, 1, 2, ..., T-1:
        - Tính Return G_t (tổng reward từ t đến T, có discount γ)
        - Update weights của neural network (Gradient Ascent):
          θ ← θ + α * G_t * ∇_θ ln π_θ(A_t|S_t)

4. Ưu nhược điểm và Baseline (REINFORCE with Baseline)

Ưu điểm của Policy Gradient:

  • Xử lý mượt mà Continuous Action Spaces (Không gian hành động liên tục).
  • Có thể học được Stochastic Policies (chính sách mang tính ngẫu nhiên). Trong game Kéo-Búa-Bao, nếu chơi Deterministic (luôn ra 1 búa), bạn sẽ bị đối thủ bắt bài. Policy Gradient có thể tự động học ra tỷ lệ 33-33-33 để tối ưu hóa.

Nhược điểm chí mạng của REINFORCE:

  • High Variance (Phương sai cực cao): Vì nó là thuật toán Monte Carlo, nó phải đợi đến cuối episode mới có GtG_t. Một ván game có cả ngàn step, chỉ vì 1 step ngu ở cuối mà GtG_t bị âm, thuật toán sẽ "đổ vạ" cho cả 999 step đúng trước đó. Điều này làm cho quá trình hội tụ cực kỳ rung lắc và bất ổn.
  • Sample Inefficiency: Chơi xong ván nào, học ván đó, rồi vứt data đi (On-policy). Rất tốn kém data.

Cách khắc phục Variance: Dùng Baseline (b) Thay vì nhân thẳng với GtG_t, người ta thường trừ GtG_t cho một cái baseline b(s)b(s) nào đó.

θt+1θt+α(Gtb(s))θlnπθ(AtSt)\theta_{t+1} \leftarrow \theta_t + \alpha (G_t - b(s)) \nabla_\theta \ln \pi_\theta(A_t|S_t)

Về mặt toán học, người ta chứng minh được việc trừ đi baseline b(s)b(s) (miễn là nó không phụ thuộc vào action) sẽ không làm thay đổi giá trị kỳ vọng của gradient, nhưng lại làm giảm phương sai (variance) đi cực kỳ nhiều! Trong thực tế, baseline tốt nhất chính là State-Value Function V(s)V(s). Lúc này, (GtV(s))(G_t - V(s)) chính là Advantage (Lợi thế). Nó cho ta biết: Hành động ta vừa làm (GtG_t) thực sự tốt hơn mức trung bình kỳ vọng ở state này (V(s)V(s)) là bao nhiêu.

Sự kết hợp giữa Policy Gradient (để chọn action) và Value Function (để làm baseline/critic đánh giá action) đã mở ra một kỷ nguyên mới, mạnh mẽ nhất của RL: Các thuật toán Actor-Critic.


Đôi lời trước khi kết thúc

Policy Gradient có thể xem là một bước chuyển mình của RL để vươn ra khỏi các bài toán Toy-game và bước vào thế giới Robotics hay Autonomous Driving (thế giới Continuous Control). Tuy nhiên, REINFORCE thuần túy vẫn còn quá nhiều điểm yếu về mặt tối ưu và độ ổn định.

Cảm ơn các bạn đã theo dõi!

References:

  • Sutton, R. S., & Barto, A. G. (2018). Reinforcement Learning: An Introduction

All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.