Thuật toán Học tăng cường SARSA trong Python: Hướng dẫn đầy đủ
Tìm hiểu SARSA, một thuật toán học tăng cường on-policy. Hiểu quy tắc cập nhật, siêu tham số và khác biệt với Q-learning kèm ví dụ Python thực tế và cách triển khai.
Học tăng cường (RL) là một mô hình học máy mạnh mẽ. Trong RL, phần mềm, thường gọi là tác tử (agent), học cách tương tác với môi trường để giải quyết các bài toán phức tạp thông qua thử và sai, hoàn toàn không cần con người can thiệp. Trong số các thuật toán RL, SARSA nổi bật nhờ đặc tính on-policy hiệu quả.
SARSA là viết tắt của State-Action-Reward-State-Action (Trạng thái–Hành động–Phần thưởng–Trạng thái–Hành động), đại diện cho một chu trình mà tác tử tuân theo để giải quyết vấn đề. Chu trình này cho phép tác tử học từ những sai lầm trước đó và đôi khi mạo hiểm thử điều mới. Hành vi này giúp thuật toán đặc biệt hiệu quả với một số loại bài toán cụ thể và tạo khác biệt với các thuật toán off-policy như Q-learning.
Trong hướng dẫn này, bạn sẽ học cách SARSA hoạt động và cách triển khai nó trong Python. Để việc hiểu trở nên cụ thể, chúng ta sẽ sử dụng một bài toán cổ điển: Taxi Ride. Chúng ta cũng sẽ thảo luận ưu điểm, hạn chế và ứng dụng thực tế của SARSA.
SARSA là gì? Câu trả lời ngắn gọn
SARSA, viết tắt của State-Action-Reward-State-Action, mô tả một chuỗi sự kiện trong quá trình học. Đây là một phương pháp học hiệu quả để các chương trình máy tính (tác tử) đưa ra quyết định tốt trong nhiều tình huống khác nhau.
Ý tưởng chính đằng sau SARSA là thử và sai. Tác tử thực hiện một hành động trong một tình huống, quan sát kết quả và điều chỉnh chiến lược dựa trên kết quả đó (tốt hay xấu). Quá trình này được lặp lại nhiều lần, dẫn đến việc cải thiện dần các quyết định của tác tử theo thời gian.
Điều khiến SARSA trở nên đặc biệt trong các thuật toán RL là SARSA học từ chính những lựa chọn thực tế mà tác tử đưa ra, kể cả khi đang thử nghiệm điều mới. Cách tiếp cận này đặc biệt hữu ích khi hành trình học quan trọng không kém kết quả cuối cùng.
Giống như một robot học đi xe đạp bằng cách thực sự đạp xe, ngã rồi đứng dậy, thay vì chỉ tìm đường ngắn nhất từ A đến B bằng bánh phụ an toàn.
Thiết lập môi trường cho hướng dẫn
Trong hướng dẫn này, chúng ta sẽ sử dụng nhiều Numpy và thư viện Gymnasium cho học tăng cường. Numpy sẽ giúp chúng ta viết thuật toán SARSA, còn Gymnasium cung cấp sẵn các môi trường để kiểm thử.
Hãy cài đặt chúng trong một môi trường ảo mới với các lệnh sau:
$ conda create -n sarsa python=3.9-y
$ conda activate sarsa
$ pip install"gymnasium[atari]" numpy matplotlib
$ pip install autorom[accept-rom-license]# Downloading Gym env data files
$ AutoROM --accept-license # Accepting the license for data files
$ pip install ipykernel # Install Jupyter kernel manager
$ ipython kernel install--user--name=sarsa # Add the new Conda env to JupyterĐược hỗ trợ bởi
Trước khi tiếp tục, tôi rất khuyến khích bạn đọc bài viếtGiới thiệu về Học tăng cường của chúng tôi. Bài viết đề cập các ý tưởng nền tảng của RL, như tác tử, môi trường, tiến thoái lưỡng nan giữa khám phá và khai thác, và Q-learning.
Giải thích môi trường Taxi-V3
Xuyên suốt hướng dẫn, chúng ta sẽ dùng môi trường Taxi-v3, một bài toán RL cổ điển do thư viện Gymnasium cung cấp. Nó mô phỏng một tài xế taxi điều hướng trong thế giới lưới 5x5 để đón và trả khách.
Để tải môi trường, chúng ta dùng phương thức .make() của Gymnasium với chế độ kết xuất rgb_array (để trực quan hóa môi trường sau này):
import gymnasium as gym
env = gym.make('Taxi-v3', render_mode='rgb_array')Được hỗ trợ bởi
Môi trường là một lưới 5x5 với bốn vị trí được chỉ định: đỏ (R), xanh lá (G), vàng (Y) và xanh dương (B). Taxi bắt đầu tại một ô ngẫu nhiên và phải đón hành khách tại một trong các vị trí màu và trả họ ở vị trí màu khác.
Taxi có thể di chuyển Bắc, Nam, Đông hoặc Tây và cũng có thể thử đón hoặc trả hành khách.
Dưới đây là cách chúng ta trực quan hóa trạng thái ban đầu của môi trường với Matplotlib:
import matplotlib.pyplot as plt
# Reset the environment to get an initial state# Each time we reset the environment, we get a new random state
initial_state, _ = env.reset()# Render the initial state
img = env.render()# Create a figure and display the environment
fig, ax = plt.subplots(figsize=(8,8))
ax.imshow(img)# Remove axis ticks
ax.set_xticks([])
ax.set_yticks([]);Được hỗ trợ bởi
Đầu tiên, chúng ta reset môi trường để nhận trạng thái ban đầu. Sau đó, hiển thị trạng thái này bằng hàm render, nhận về một mảng ảnh Numpy. Hàm imshow() của Matplotlib nhận mảng này và tạo hình ảnh trực quan gọn gàng không có vạch trục.
Hãy dành chút thời gian để hiểu bố cục của thế giới lưới Taxi-v3, lưu ý vị trí taxi, các rào chắn, vị trí hành khách và điểm đến.
Tác tử (chiếc taxi) nhận +20 điểm khi trả khách thành công. Đón hoặc trả sai chỗ bị phạt -10. Đồng thời, mỗi bước thời gian bị phạt -1 để khuyến khích taxi hoàn thành nhiệm vụ nhanh chóng.
Một tập (episode) của môi trường Taxi-v3 sẽ kết thúc khi trả khách thành công hoặc khi đạt số bước tối đa.
# The number of states and actions
n_states = env.observation_space.n
n_actions = env.action_space.n
print(n_states)print(n_actions)Được hỗ trợ bởi
Có 500 trạng thái trong không gian trạng thái của môi trường. Mỗi trạng thái được biểu diễn bởi:
Hàng của taxi (0–4)
Cột của taxi (0–4)
Vị trí hành khách (0–3 ứng với R, G, Y, B, hoặc 4 nếu ở trong taxi)
Điểm đến (0–3 ứng với R, G, Y, B)
Tổng trạng thái = 5 (hàng)×5 (cột)×5 (vị trí hành khách)×4 (điểm đến)=500.
Mã hành động gồm:
0: Đi về Nam
1: Đi về Bắc
2: Đi về Đông
3: Đi về Tây
4: Đón hành khách
5: Trả hành khách
Mục tiêu là để tác tử học một chính sách tối ưu nhằm tối đa hóa tổng phần thưởng bằng cách đón và trả khách hiệu quả.
Vòng lặp tương tác SARSA
Trước khi viết toàn bộ thuật toán, hãy xem chu trình Trạng thái–Hành động–Phần thưởng–Trạng thái–Hành động vận hành ra sao trong môi trường của chúng ta.
Trước hết, ta xác định số tập muốn vòng tương tác tiếp diễn. Một tập đại diện cho một lần chạy đầy đủ nhiệm vụ taxi, từ trạng thái ban đầu đến khi trả khách thành công hoặc đạt số bước tối đa. Mỗi tập cho phép tác tử học từ trải nghiệm và cải thiện chiến lược theo thời gian.
for episode inrange(n_episodes):
state, _ = env.reset()
done =False
total_reward =0
steps =0whilenot done:# Choose a random action
action = env.action_space.sample()# Take the action and observe the result
next_state, reward, terminated, truncated, _ = env.step(action)
done = terminated or truncated
# Update total reward and step count
total_reward += reward
steps +=1# Move to the next state
state = next_state
if episode %1000==0:print(f"Episode {episode}, Total Reward: {total_reward}, Steps: {steps}")Được hỗ trợ bởi
Episode 0, Total Reward: -812, Steps: 200
Episode 1000, Total Reward: -830, Steps: 200
Episode 2000, Total Reward: -902, Steps: 200
Episode 3000, Total Reward: -522, Steps: 129
Episode 4000, Total Reward: -767, Steps: 200Được hỗ trợ bởi
Đoạn mã trên minh họa chu trình tương tác SARSA cơ bản mà chưa triển khai bất kỳ thuật toán học nào:
Reset môi trường ở đầu mỗi tập — (S), env.reset().
Thực hiện một hành động ngẫu nhiên — (A), env.step(action). Phiên bản này dùng hành động ngẫu nhiên để minh họa vòng lặp tương tác.
Nhận phần thưởng (R) và trạng thái tiếp theo (S_1), next_state, reward, ... = env.take(action).
Thực hiện hành động (A_1) ở trạng thái mới.
Trong vòng lặp tương tác trên, taxi cứ di chuyển khắp môi trường theo mọi hướng và thực hiện các hành động ngẫu nhiên cho đến khi hết bước thời gian.
Tạo hoạt ảnh cho vòng lặp tương tác SARSA
Trước khi tiếp tục, hãy triển khai một tính năng để tạo hoạt ảnh cho các vòng lặp tương tác. Điều này cho phép chúng ta trực quan thấy taxi tương tác với môi trường.
Việc tạo hoạt ảnh sẽ khá đơn giản:
Ở mỗi bước thời gian, ta chụp lại trạng thái của môi trường thành một mảng ảnh bằng hàm env.render().
Chúng ta thu thập các mảng ảnh này trong một biến riêng.
Dùng thư viện moviepy, chúng ta nối tất cả mảng ảnh để tạo thành một GIF.
Hãy sửa mã như sau:
env = gym.make("Taxi-v3", render_mode="rgb_array")
n_episodes =1
frames =[]# for animationfor episode inrange(n_episodes):# Reset the environment
state, _ = env.reset()# Capture the state as an image
img = env.render()
frames.append(img)
done =False
total_reward =0
steps =0whilenot done:# Choose a random action
action = env.action_space.sample()# Take the action and observe the result
next_state, reward, terminated, truncated, _ = env.step(action)
done = terminated or truncated
# Capture the next state as an image
img = env.render()
frames.append(img)# Update total reward and step count
total_reward += reward
steps +=1# Move to the next state
state = next_stateĐược hỗ trợ bởi
Ở phiên bản này, chúng ta đặt số tập chỉ là một, vì kết xuất trạng thái môi trường thành ảnh khá tốn thời gian. Ta cũng tạo một danh sách rỗng để lưu các mảng ảnh. Sau đó, vòng lặp tương tác diễn ra như trước. Khác biệt duy nhất là hai dòng bổ sung để kết xuất môi trường thành ảnh và thêm vào frames.
Bây giờ, chúng ta phải có 201 ảnh trong frames (một ảnh dư cho trạng thái bổ sung):
Hãy chuyển các ảnh này thành một GIF bằng thư viện moviepy:
from moviepy.editor import ImageSequenceClip # pip install moviepydefcreate_gif(frames:list, filename, fps=5):"""
Creates a GIF animation from a list of RGBA NumPy arrays.
Args:
frames: A list of RGBA NumPy arrays representing the animation frames.
filename: The output filename for the GIF animation.
fps: The frames per second of the animation (default: 10).
"""
clip = ImageSequenceClip(frames, fps=fps)
clip.write_gif(filename, fps=fps)# Example usage
create_gif(frames,"animation.gif", fps=25)# saves the GIF locallyĐược hỗ trợ bởi
Hàm create_gif() nhận danh sách khung hình và chuyển chúng thành một GIF bằng lớp ImageSequenceClip của moviepy. Tham số quan trọng là số khung hình mỗi giây, fps, điều khiển độ dài GIF. Càng nhiều khung hình mỗi giây, GIF càng ngắn.
Cuối cùng, chúng ta chuyển các khung hình của một tập thành GIF với 25 FPS. Đây là kết quả:
Như bạn thấy, taxi không biết mình đang làm gì và thậm chí không đến gần hành khách. Hãy cho nó chút “bộ não” bằng cách thêm SARSA vào hệ thống điều hướng.
Triển khai SARSA trong Python từng bước
Chúng ta sẽ xây dựng mã cho SARSA từ đầu để bạn ghi nhớ rõ từng bước.
1. Thiết lập môi trường Gymnasium:
import gymnasium as gym
import numpy as np
import matplotlib.pyplot as plt
# Create the Taxi environment
env = gym.make("Taxi-v3", render_mode="rgb_array")Được hỗ trợ bởi
Ở bước này, chúng ta giới thiệu một cấu trúc dữ liệu mới — Q-table. Nó có kích thước (số trạng thái) x (số hành động). Bảng sẽ trông như thế này đối với tác tử, người lái taxi:
Sau đó, khi tác tử bắt đầu tương tác với môi trường dưới sự dẫn dắt của SARSA, nó sẽ cập nhật Q-table với các Q-value. Q-value là các điểm số cho biết hành động nào là tốt nhất cần thực hiện tại một trạng thái nhất định.
3. Định nghĩa siêu tham số của SARSA
Sau khi khởi tạo Q-table, chúng ta đặt các siêu tham số của SARSA về các giá trị thường dùng (sẽ bàn thêm sau):
Tiếp theo, chúng ta định nghĩa hai danh sách để lưu các chỉ số hiệu năng: tổng phần thưởng và số bước thời gian cho mỗi tập. Mục tiêu của tác tử là thu được càng nhiều phần thưởng càng tốt trong thời gian ngắn nhất có thể:
# Lists to store performance metrics
episode_rewards =[]
episode_lengths =[]Được hỗ trợ bởi
5. Chính sách epsilon-greedy để thực hiện hành động
Ở phần trước, tác tử của chúng ta chưa được dẫn dắt — nó thực hiện hành động ngẫu nhiên. Chúng ta muốn thay đổi điều đó bằng cách cho người lái một chiến lược Epsilon-Greedy:
defepsilon_greedy(state, epsilon):if np.random.random()< epsilon:# Take random action - explorereturn env.action_space.sample()else:# Take action with the highest Q-value - exploitreturn np.argmax(Q_table[state])Được hỗ trợ bởi
Chiến lược này nhằm kiểm soát cân bằng then chốt giữa khám phá và khai thác. Với xác suất epsilon, tác tử khám phá môi trường bằng cách thực hiện hành động ngẫu nhiên, còn với xác suất 1-epsilon, nó khai thác kiến thức hiện có bằng cách chọn hành động có Q-value cao nhất từ Q-table. Cách tiếp cận này cho phép tác tử khám phá các chiến lược mới có thể tốt hơn đồng thời sử dụng những gì đã học.
6. Viết vòng lặp huấn luyện SARSA
Cuối cùng, chúng ta viết vòng lặp huấn luyện SARSA. Phần đầu của vòng lặp đã quen thuộc. Khác biệt duy nhất là chúng ta dùng hàm epsilon_greedy() để quyết định hành động cần thực hiện ở trạng thái hiện tại:
Sau đó, chúng ta bắt đầu vòng lặp while cho phép chạy chu trình tương tác cho đến khi đạt trạng thái kết thúc:
# SARSA training loopfor episode inrange(n_episodes):...whilenot done:
next_state, reward, terminated, truncated, _ = env.step(action)
done = terminated or truncated
next_action = epsilon_greedy(next_state, epsilon)Được hỗ trợ bởi
Bên trong vòng lặp while, chúng ta thực hiện hành động do epsilon_greedy() trả về và nhận trạng thái tiếp theo, phần thưởng cho hành động, cùng giá trị boolean cho biết tập đã kết thúc hay chưa.
Tiếp theo là phần then chốt — quy tắc cập nhật của SARSA:
Chúng ta sẽ học trực giác đằng sau công thức này ở phần tiếp theo. Hiện tại, hãy coi công thức như “phép màu” toán học cập nhật Q-value của Q-table theo quy tắc của SARSA.
Sau khi cập nhật Q, chúng ta đổi biến state và action sang trạng thái và hành động kế tiếp, cộng phần thưởng nhận được vào tổng phần thưởng của tập, và tăng số bước thời gian.
# SARSA training loopfor episode inrange(n_episodes):...whilenot done:...
state = next_state
action = next_action
total_reward += reward
steps +=1Được hỗ trợ bởi
Vòng lặp while tiếp tục cho đến khi đạt số bước tối đa (200 với môi trường taxi) hoặc khi taxi trả khách thành công tại vị trí đúng.
Khi vòng lặp kết thúc, ta ghi nhận tổng phần thưởng và độ dài tập. Chúng ta cũng in phần thưởng và độ dài trung bình mỗi 1000 tập:
Như bạn thấy từ đầu ra, phần thưởng trung bình và số bước mỗi tập đã giảm mạnh khi chúng ta chạy ngày càng nhiều tập.
Chúng ta có thể thấy điều này trực quan bằng cách vẽ các mảng episode_rewards và episode_lengths:
# Plot the learning curve
plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plt.plot(episode_rewards)
plt.title("Episode Rewards")
plt.xlabel("Episode")
plt.ylabel("Total Reward")
plt.subplot(1,2,2)
plt.plot(episode_lengths)
plt.title("Episode Lengths")
plt.xlabel("Episode")
plt.ylabel("Number of Steps")
plt.tight_layout()
plt.show()Được hỗ trợ bởi
Biểu đồ bên trái hiển thị tổng phần thưởng thu được ở mỗi tập. Ta có thể quan sát rằng:
Ban đầu, phần thưởng thấp và biến động mạnh, cho thấy tác tử đang khám phá và học.
Theo thời gian, có xu hướng tăng dần phần thưởng, cho thấy tác tử đang cải thiện chính sách.
Về cuối, phần thưởng dường như ổn định ở mức cao hơn, chỉ ra rằng tác tử đã học được một chính sách khá tốt.
Biểu đồ bên phải cho thấy số bước thực hiện trong mỗi tập. Ta có thể thấy rằng:
Lúc đầu, các tập có xu hướng dài hơn, vì tác tử thực hiện hành động kém tối ưu.
Khi việc học tiến triển, có xu hướng giảm dần độ dài tập.
Độ dài tập cuối cùng ổn định, cho thấy tác tử đã học cách hoàn thành nhiệm vụ hiệu quả hơn.
Tổ chức mã thành các hàm
Trong thời gian ngắn, chúng ta đã bao quát khá nhiều nội dung. Giờ hãy lùi lại một bước và tổ chức mọi thứ đã viết. Chúng ta sẽ tạo các hàm cho từng bước đã thực hiện để triển khai SARSA.
Đầu tiên, một hàm tạo môi trường:
import gymnasium as gym
import numpy as np
import matplotlib.pyplot as plt
from moviepy.editor import ImageSequenceClip
defcreate_environment(env_name="Taxi-v3", render_mode="rgb_array"):"""Create and return a Gymnasium environment."""return gym.make(env_name, render_mode=render_mode)Được hỗ trợ bởi
Tiếp theo, một hàm khởi tạo Q-table cho một môi trường:
definitialize_q_table(env):"""Initialize and return a Q-table for the given environment."""
n_states = env.observation_space.n
n_actions = env.action_space.n
return np.zeros((n_states, n_actions))Được hỗ trợ bởi
Chiến lược Epsilon-greedy nhận môi trường, Q-table, trạng thái hiện tại và epsilon:
Quy tắc cập nhật của SARSA, yêu cầu Q-table, trạng thái hiện tại, hành động đã thực hiện ở trạng thái đó, phần thưởng cho hành động, trạng thái và hành động tiếp theo:
defplot_learning_curve(episode_rewards, episode_lengths):"""Plot the learning curve."""
plt.figure(figsize=(12,5))
plt.subplot(1,2,1)
plt.plot(episode_rewards)
plt.title("Episode Rewards")
plt.xlabel("Episode")
plt.ylabel("Total Reward")
plt.subplot(1,2,2)
plt.plot(episode_lengths)
plt.title("Episode Lengths")
plt.xlabel("Episode")
plt.ylabel("Number of Steps")
plt.tight_layout()
plt.show()Được hỗ trợ bởi
Hàm create_gif() mà chúng ta đã dùng trước đó:
defcreate_gif(frames, filename, fps=5):"""Creates a GIF animation from a list of frames."""
clip = ImageSequenceClip(frames, fps=fps)
clip.write_gif(filename, fps=fps)Được hỗ trợ bởi
Và một hàm khác để chạy một tập duy nhất kèm kết xuất hình ảnh dùng Q-table đã học hoàn chỉnh (phục vụ tạo hoạt ảnh):
defrun_episode(env, Q_table, epsilon=0):"""Run a single episode using the learned Q-table."""
state, _ = env.reset()
done =False
total_reward =0
frames =[env.render()]whilenot done:
action = epsilon_greedy(env, Q_table, state, epsilon)
next_state, reward, terminated, truncated, _ = env.step(action)
done = terminated or truncated
frames.append(env.render())
total_reward += reward
state = next_state
return frames, total_rewardĐược hỗ trợ bởi
Trọng tâm của SARSA là quy tắc cập nhật, điều khiển cách tác tử học từ trải nghiệm. Hãy phân tích quy tắc này và khám phá trực giác đằng sau nó:
Q(s, a) = Q(s, a) + α [R + γ Q(s', a') - Q(s, a)]
Hiểu các thành phần
Q(s, a): Q-value hiện tại của việc thực hiện hành động ‘a’ tại trạng thái ‘s’.
α (alpha): Tốc độ học, kiểm soát mức độ tích hợp thông tin mới.
R: Phần thưởng nhận được sau khi thực hiện hành động.
γ (gamma): Hệ số chiết khấu, xác định tầm quan trọng của phần thưởng tương lai.
Q(s’, a’): Q-value ước lượng của cặp trạng thái–hành động tiếp theo.
Quá trình học
Quy tắc cập nhật của SARSA nhằm tinh chỉnh sự hiểu biết của tác tử về môi trường bằng cách điều chỉnh Q-value dựa trên trải nghiệm mới. Cách hoạt động như sau:
Tác tử thực hiện một hành động và quan sát phần thưởng cùng trạng thái tiếp theo.
Nó tính chênh lệch giữa Q-value hiện tại và ước lượng Q-value mới dựa trên phần thưởng quan sát được và giá trị của cặp trạng thái–hành động tiếp theo.
Chênh lệch này, sau khi nhân với tốc độ học, được dùng để cập nhật Q-value.
Sai số sai biệt theo thời gian
Hạng tử [R + γ * Q(s’, a’) — Q(s, a)] được gọi là sai số sai biệt theo thời gian (TD error). Hãy coi nó như thước đo mức độ “ngạc nhiên”:
TD dương: Kết quả tốt hơn mong đợi.
TD âm: Kết quả tệ hơn mong đợi.
TD bằng 0: Kết quả khớp hoàn hảo với ước lượng hiện tại.
Sai số này giúp tác tử liên tục tinh chỉnh ước lượng, thúc đẩy quá trình học hướng tới một chính sách tối ưu.
Vai trò của các siêu tham số
1. Tốc độ học (α):
Điều khiển tốc độ học.
α cao: Học nhanh hơn nhưng có thể kém ổn định.
α thấp: Học chậm hơn nhưng ổn định hơn.
2. Hệ số chiết khấu (γ):
Cân bằng giữa phần thưởng tức thời và tương lai.
γ gần 1: Tác tử coi trọng phần thưởng tương lai gần như tương đương phần thưởng tức thời.
γ thấp: Tác tử tập trung nhiều hơn vào phần thưởng tức thời.
3. Tỷ lệ khám phá (ε):
Dù không nằm trong quy tắc cập nhật, nhưng nó rất quan trọng với chính sách epsilon-greedy.
Cân bằng giữa khám phá (thử hành động mới) và khai thác (dùng hành động đã biết là tốt).
ε cao: Khám phá nhiều hơn, có thể khám phá chiến lược tốt hơn với cái giá là hiệu năng ngắn hạn.
Bức tranh tổng thể
Quy tắc cập nhật của SARSA cho phép tác tử học từ trải nghiệm bằng cách liên tục điều chỉnh ước lượng giá trị trạng thái–hành động. Với mỗi tương tác, tác tử “khôn” hơn đôi chút về môi trường của mình. Qua nhiều tập, quá trình này dẫn tới việc hình thành một chính sách tối ưu để điều hướng môi trường.
Bằng cách tinh chỉnh các siêu tham số, chúng ta có thể kiểm soát nhiều khía cạnh của quá trình học, cho phép SARSA thích ứng với các loại bài toán và môi trường khác nhau. Tính linh hoạt này, kết hợp với quy tắc cập nhật trực quan, khiến SARSA trở thành một thuật toán học tăng cường mạnh mẽ và được sử dụng rộng rãi.
SARSA so với Q-learning: Khác biệt chính
Dù SARSA và Q-learning đều là các thuật toán học tăng cường được dùng rộng rãi, chúng có một số khác biệt quan trọng. Những khác biệt này then chốt để hiểu khi nào và cách dùng mỗi thuật toán.
1. On-policy so với off-policy
Là một thuật toán on-policy, SARSA học giá trị của chính sách mà nó đang theo, kể cả những bước đi trong lúc khám phá. Q-learning là off-policy; nó học giá trị của chính sách tối ưu — ngay cả khi không theo chính sách đó, nó vẫn học giá trị của chính sách tối ưu khi cuối cùng đến cuối tập. Đó là lý do chúng tôi đã nói từ đầu rằng nên dùng SARSA khi hành trình học quan trọng không kém kết quả. Q-learning thì không mấy bận tâm đến hành trình học.
2. Quy tắc cập nhật
SARSA: Q(s, a) = Q(s, a) + α * [R + γ * Q(s’, a’) — Q(s, a)]
Q-learning: Q(s, a) = Q(s, a) + α * [R + γ * max(Q(s’, a’)) — Q(s, a)]
Khác biệt chính là SARSA dùng Q-value của hành động tiếp theo thực sự được thực hiện (a’), trong khi Q-learning dùng Q-value lớn nhất của trạng thái tiếp theo (max(Q(s’, a’))).
3. Cân nhắc việc khám phá
Khi cập nhật Q-value, SARSA không bỏ qua chính sách khám phá nên thận trọng hơn. Ngược lại, Q-learning luôn giả định tác tử sẽ thực hiện hành động tối ưu trong tương lai nên hung hăng hơn.
4. Hội tụ
Dù cả hai cuối cùng đều đạt chính sách tối ưu, Q-learning thường học nhanh hơn, đặc biệt trong môi trường tất định.
5. An toàn
Trong các môi trường mà việc khám phá có thể dẫn đến hậu quả xấu, SARSA thường học các chính sách an toàn hơn vì nó tính đến chính sách thực tế đang được theo.
Trong bài toán “đi dọc vách đá” cổ điển, SARSA thường học một lối đi an toàn hơn, tránh xa mép vực, trong khi Q-learning có thể học lối đi mạo hiểm dọc theo mép.
6. Ổn định
Trong một số môi trường ngẫu nhiên, SARSA có thể ổn định hơn vì nó tính đến hành động tiếp theo thực tế, ngay cả khi đó là hành động thăm dò kém tối ưu.
7. Nhạy cảm với siêu tham số
Q-learning có thể nhạy cảm hơn với lựa chọn tốc độ học và tỷ lệ khám phá, đặc biệt trong môi trường có tính ngẫu nhiên lớn.
8. Ứng dụng thực tế
Với robot hoặc các hệ thống vật lý nơi việc khám phá tốn kém và chúng ta muốn triển khai các chính sách an toàn hơn, có thể ưu tiên thuật toán on-policy SARSA. Khi ở thế giới mô phỏng, trò chơi, hoặc các môi trường có nhiều phản hồi và chúng ta muốn tìm chính sách tối ưu một cách nhanh chóng và tương đối an toàn, Q-learning thường phù hợp hơn.
Vì thế, bạn có thể nghĩ rằng SARSA thuộc “trường phái an toàn”, còn Q-learning là cách tiếp cận nhanh hơn và táo bạo hơn. Trên thực tế, điều này phụ thuộc vào bài toán cụ thể. Cả hai đều rất mạnh, và việc hiểu rõ khác biệt giữa chúng luôn có ý nghĩa.
Kết luận
Trong hướng dẫn toàn diện này, chúng ta đã khám phá thuật toán SARSA, bao gồm khái niệm cốt lõi, chi tiết triển khai và ứng dụng thực tế bằng môi trường Taxi-v3.
Một số điểm chính gồm:
Tính on-policy của SARSA và trực giác về quy tắc cập nhật
Triển khai Python và các kỹ thuật trực quan hóa
So sánh với Q-learning, làm rõ điểm mạnh và trường hợp sử dụng
Khả năng học các chính sách an toàn hơn khiến SARSA phù hợp với ứng dụng thực tế nơi chi phí khám phá cao, dù trong một số kịch bản nó có thể hội tụ chậm hơn so với các thuật toán off-policy như Q-learning.
Hãy nhớ rằng việc chọn giữa SARSA và các thuật toán khác phụ thuộc vào bài toán và môi trường cụ thể. Thử nghiệm và tinh chỉnh là chìa khóa để đạt kết quả tối ưu.
Chúng tôi khuyến khích bạn xây dựng thêm trên nền tảng này bằng cách khám phá các môi trường phức tạp hơn, triển khai SARSA với xấp xỉ hàm, hoặc tìm hiểu các thuật toán học tăng cường khác.
Dưới đây là một số tài nguyên liên quan để hỗ trợ bạn:
SARSA (State-Action-Reward-State-Action) là một thuật toán học tăng cường on-policy, cập nhật Q-value dựa trên trải nghiệm thực tế của tác tử, bao gồm cả các hành động thăm dò.
SARSA khác Q-learning như thế nào?⌄
SARSA là on-policy và cập nhật Q-value bằng hành động tiếp theo thực sự được thực hiện, trong khi Q-learning là off-policy và dùng Q-value lớn nhất của trạng thái tiếp theo, dẫn đến hành vi học khác nhau.
Các siêu tham số chính trong SARSA là gì và chúng ảnh hưởng việc học ra sao?⌄
Các siêu tham số chính là tốc độ học (α), hệ số chiết khấu (γ), và tỷ lệ khám phá (ε). Chúng lần lượt kiểm soát tốc độ học, tầm quan trọng của phần thưởng tương lai, và cân bằng giữa khám phá và khai thác.
Làm thế nào để triển khai thuật toán SARSA trong Python?⌄
Bài viết cung cấp hướng dẫn từng bước để triển khai SARSA trong Python, bao gồm thiết lập môi trường, khởi tạo Q-table và viết vòng lặp huấn luyện.
Các ứng dụng thực tế của SARSA trong kịch bản đời thực là gì?⌄
SARSA phù hợp với các ứng dụng có chi phí khám phá cao, như robot và hệ thống vật lý, vì nó có xu hướng học các chính sách an toàn hơn so với các thuật toán off-policy như Q-learning.
Tôi là người sáng tạo nội dung về khoa học dữ liệu với hơn 2 năm kinh nghiệm và là một trong những tài khoản có lượng người theo dõi lớn nhất trên Medium. Tôi thích viết các bài chuyên sâu về AI và ML với chút giọng điệu mỉa mai, vì bạn cũng phải làm gì đó để chúng bớt khô khan. Tôi đã xuất bản hơn 130 bài viết và một khóa học trên DataCamp, cùng với một khóa nữa đang được thực hiện. Nội dung của tôi đã được hơn 5 triệu lượt xem, trong đó 20 nghìn người đã trở thành người theo dõi trên cả Medium và LinkedIn.
Học tăng cường (RL) là một mô hình học máy mạnh mẽ. Trong RL, phần mềm, thường gọi là tác tử (agent), học cách tương tác với môi trường để giải quyết các bài toán phức tạp thông qua thử và sai, hoàn toàn không cần con người can thiệp. Trong số các thuật toán RL, SARSA nổi bật nhờ đặc tính on-policy hiệu quả.
SARSA là viết tắt của State-Action-Reward-State-Action (Trạng thái–Hành động–Phần thưởng–Trạng thái–Hành động), đại diện cho một chu trình mà tác tử tuân theo để giải quyết vấn đề. Chu trình này cho phép tác tử học từ những sai lầm trước đó và đôi khi mạo hiểm thử điều mới. Hành vi này giúp thuật toán đặc biệt hiệu quả với một số loại bài toán cụ thể và tạo khác biệt với các thuật toán off-policy như Q-learning.
Trong hướng dẫn này, bạn sẽ học cách SARSA hoạt động và cách triển khai nó trong Python. Để việc hiểu trở nên cụ thể, chúng ta sẽ sử dụng một bài toán cổ điển: Taxi Ride. Chúng ta cũng sẽ thảo luận ưu điểm, hạn chế và ứng dụng thực tế của SARSA.
SARSA là gì? Câu trả lời ngắn gọn
SARSA, viết tắt của State-Action-Reward-State-Action, mô tả một chuỗi sự kiện trong quá trình học. Đây là một phương pháp học hiệu quả để các chương trình máy tính (tác tử) đưa ra quyết định tốt trong nhiều tình huống khác nhau.
Ý tưởng chính đằng sau SARSA là thử và sai. Tác tử thực hiện một hành động trong một tình huống, quan sát kết quả và điều chỉnh chiến lược dựa trên kết quả đó (tốt hay xấu). Quá trình này được lặp lại nhiều lần, dẫn đến việc cải thiện dần các quyết định của tác tử theo thời gian.
Điều khiến SARSA trở nên đặc biệt trong các thuật toán RL là SARSA học từ chính những lựa chọn thực tế mà tác tử đưa ra, kể cả khi đang thử nghiệm điều mới. Cách tiếp cận này đặc biệt hữu ích khi hành trình học quan trọng không kém kết quả cuối cùng.
Giống như một robot học đi xe đạp bằng cách thực sự đạp xe, ngã rồi đứng dậy, thay vì chỉ tìm đường ngắn nhất từ A đến B bằng bánh phụ an toàn.
Thiết lập môi trường cho hướng dẫn
Trong hướng dẫn này, chúng ta sẽ sử dụng nhiều Numpy và thư viện Gymnasium cho học tăng cường. Numpy sẽ giúp chúng ta viết thuật toán SARSA, còn Gymnasium cung cấp sẵn các môi trường để kiểm thử.
Hãy cài đặt chúng trong một môi trường ảo mới với các lệnh sau:
Trước khi tiếp tục, tôi rất khuyến khích bạn đọc bài viết Giới thiệu về Học tăng cường của chúng tôi. Bài viết đề cập các ý tưởng nền tảng của RL, như tác tử, môi trường, tiến thoái lưỡng nan giữa khám phá và khai thác, và Q-learning.
Giải thích môi trường Taxi-V3
Xuyên suốt hướng dẫn, chúng ta sẽ dùng môi trường Taxi-v3, một bài toán RL cổ điển do thư viện Gymnasium cung cấp. Nó mô phỏng một tài xế taxi điều hướng trong thế giới lưới 5x5 để đón và trả khách.
Để tải môi trường, chúng ta dùng phương thức
.make()của Gymnasium với chế độ kết xuấtrgb_array(để trực quan hóa môi trường sau này):Môi trường là một lưới 5x5 với bốn vị trí được chỉ định: đỏ (R), xanh lá (G), vàng (Y) và xanh dương (B). Taxi bắt đầu tại một ô ngẫu nhiên và phải đón hành khách tại một trong các vị trí màu và trả họ ở vị trí màu khác.
Taxi có thể di chuyển Bắc, Nam, Đông hoặc Tây và cũng có thể thử đón hoặc trả hành khách.
Dưới đây là cách chúng ta trực quan hóa trạng thái ban đầu của môi trường với Matplotlib:
Đầu tiên, chúng ta reset môi trường để nhận trạng thái ban đầu. Sau đó, hiển thị trạng thái này bằng hàm
render, nhận về một mảng ảnh Numpy. Hàmimshow()của Matplotlib nhận mảng này và tạo hình ảnh trực quan gọn gàng không có vạch trục.Hãy dành chút thời gian để hiểu bố cục của thế giới lưới Taxi-v3, lưu ý vị trí taxi, các rào chắn, vị trí hành khách và điểm đến.
Tác tử (chiếc taxi) nhận +20 điểm khi trả khách thành công. Đón hoặc trả sai chỗ bị phạt -10. Đồng thời, mỗi bước thời gian bị phạt -1 để khuyến khích taxi hoàn thành nhiệm vụ nhanh chóng.
Một tập (episode) của môi trường Taxi-v3 sẽ kết thúc khi trả khách thành công hoặc khi đạt số bước tối đa.
Có 500 trạng thái trong không gian trạng thái của môi trường. Mỗi trạng thái được biểu diễn bởi:
Mã hành động gồm:
Mục tiêu là để tác tử học một chính sách tối ưu nhằm tối đa hóa tổng phần thưởng bằng cách đón và trả khách hiệu quả.
Vòng lặp tương tác SARSA
Trước khi viết toàn bộ thuật toán, hãy xem chu trình Trạng thái–Hành động–Phần thưởng–Trạng thái–Hành động vận hành ra sao trong môi trường của chúng ta.
Trước hết, ta xác định số tập muốn vòng tương tác tiếp diễn. Một tập đại diện cho một lần chạy đầy đủ nhiệm vụ taxi, từ trạng thái ban đầu đến khi trả khách thành công hoặc đạt số bước tối đa. Mỗi tập cho phép tác tử học từ trải nghiệm và cải thiện chiến lược theo thời gian.
Giờ, chúng ta viết vòng lặp tương tác:
Đoạn mã trên minh họa chu trình tương tác SARSA cơ bản mà chưa triển khai bất kỳ thuật toán học nào:
env.reset().env.step(action). Phiên bản này dùng hành động ngẫu nhiên để minh họa vòng lặp tương tác.next_state,reward,... = env.take(action).Trong vòng lặp tương tác trên, taxi cứ di chuyển khắp môi trường theo mọi hướng và thực hiện các hành động ngẫu nhiên cho đến khi hết bước thời gian.
Tạo hoạt ảnh cho vòng lặp tương tác SARSA
Trước khi tiếp tục, hãy triển khai một tính năng để tạo hoạt ảnh cho các vòng lặp tương tác. Điều này cho phép chúng ta trực quan thấy taxi tương tác với môi trường.
Việc tạo hoạt ảnh sẽ khá đơn giản:
env.render().moviepy, chúng ta nối tất cả mảng ảnh để tạo thành một GIF.Hãy sửa mã như sau:
Ở phiên bản này, chúng ta đặt số tập chỉ là một, vì kết xuất trạng thái môi trường thành ảnh khá tốn thời gian. Ta cũng tạo một danh sách rỗng để lưu các mảng ảnh. Sau đó, vòng lặp tương tác diễn ra như trước. Khác biệt duy nhất là hai dòng bổ sung để kết xuất môi trường thành ảnh và thêm vào
frames.Bây giờ, chúng ta phải có 201 ảnh trong frames (một ảnh dư cho trạng thái bổ sung):
Hãy chuyển các ảnh này thành một GIF bằng thư viện
moviepy:Hàm
create_gif()nhận danh sách khung hình và chuyển chúng thành một GIF bằng lớpImageSequenceClipcủamoviepy. Tham số quan trọng là số khung hình mỗi giây, fps, điều khiển độ dài GIF. Càng nhiều khung hình mỗi giây, GIF càng ngắn.Cuối cùng, chúng ta chuyển các khung hình của một tập thành GIF với 25 FPS. Đây là kết quả:
Như bạn thấy, taxi không biết mình đang làm gì và thậm chí không đến gần hành khách. Hãy cho nó chút “bộ não” bằng cách thêm SARSA vào hệ thống điều hướng.
Triển khai SARSA trong Python từng bước
Chúng ta sẽ xây dựng mã cho SARSA từ đầu để bạn ghi nhớ rõ từng bước.
1. Thiết lập môi trường Gymnasium:
2. Khởi tạo Q-table
Ở bước này, chúng ta giới thiệu một cấu trúc dữ liệu mới — Q-table. Nó có kích thước (số trạng thái) x (số hành động). Bảng sẽ trông như thế này đối với tác tử, người lái taxi:
Ban đầu, Q-table sẽ được điền toàn số 0:
Sau đó, khi tác tử bắt đầu tương tác với môi trường dưới sự dẫn dắt của SARSA, nó sẽ cập nhật Q-table với các Q-value. Q-value là các điểm số cho biết hành động nào là tốt nhất cần thực hiện tại một trạng thái nhất định.
3. Định nghĩa siêu tham số của SARSA
Sau khi khởi tạo Q-table, chúng ta đặt các siêu tham số của SARSA về các giá trị thường dùng (sẽ bàn thêm sau):
4. Định nghĩa nơi lưu trữ các chỉ số hiệu năng
Tiếp theo, chúng ta định nghĩa hai danh sách để lưu các chỉ số hiệu năng: tổng phần thưởng và số bước thời gian cho mỗi tập. Mục tiêu của tác tử là thu được càng nhiều phần thưởng càng tốt trong thời gian ngắn nhất có thể:
5. Chính sách epsilon-greedy để thực hiện hành động
Ở phần trước, tác tử của chúng ta chưa được dẫn dắt — nó thực hiện hành động ngẫu nhiên. Chúng ta muốn thay đổi điều đó bằng cách cho người lái một chiến lược Epsilon-Greedy:
Chiến lược này nhằm kiểm soát cân bằng then chốt giữa khám phá và khai thác. Với xác suất
epsilon, tác tử khám phá môi trường bằng cách thực hiện hành động ngẫu nhiên, còn với xác suất1-epsilon, nó khai thác kiến thức hiện có bằng cách chọn hành động có Q-value cao nhất từ Q-table. Cách tiếp cận này cho phép tác tử khám phá các chiến lược mới có thể tốt hơn đồng thời sử dụng những gì đã học.6. Viết vòng lặp huấn luyện SARSA
Cuối cùng, chúng ta viết vòng lặp huấn luyện SARSA. Phần đầu của vòng lặp đã quen thuộc. Khác biệt duy nhất là chúng ta dùng hàm
epsilon_greedy()để quyết định hành động cần thực hiện ở trạng thái hiện tại:Sau đó, chúng ta bắt đầu vòng lặp
whilecho phép chạy chu trình tương tác cho đến khi đạt trạng thái kết thúc:Bên trong vòng lặp
while, chúng ta thực hiện hành động doepsilon_greedy()trả về và nhận trạng thái tiếp theo, phần thưởng cho hành động, cùng giá trị boolean cho biết tập đã kết thúc hay chưa.Tiếp theo là phần then chốt — quy tắc cập nhật của SARSA:
Quy tắc cập nhật xuất phát từ công thức sau:
[Nguồn]
Chúng ta sẽ học trực giác đằng sau công thức này ở phần tiếp theo. Hiện tại, hãy coi công thức như “phép màu” toán học cập nhật Q-value của Q-table theo quy tắc của SARSA.
Sau khi cập nhật Q, chúng ta đổi biến
statevàactionsang trạng thái và hành động kế tiếp, cộng phần thưởng nhận được vào tổng phần thưởng của tập, và tăng số bước thời gian.Vòng lặp
whiletiếp tục cho đến khi đạt số bước tối đa (200 với môi trường taxi) hoặc khi taxi trả khách thành công tại vị trí đúng.Khi vòng lặp kết thúc, ta ghi nhận tổng phần thưởng và độ dài tập. Chúng ta cũng in phần thưởng và độ dài trung bình mỗi 1000 tập:
Dưới đây là toàn bộ vòng lặp tương tác được thực thi:
Như bạn thấy từ đầu ra, phần thưởng trung bình và số bước mỗi tập đã giảm mạnh khi chúng ta chạy ngày càng nhiều tập.
Chúng ta có thể thấy điều này trực quan bằng cách vẽ các mảng
episode_rewardsvàepisode_lengths:Biểu đồ bên trái hiển thị tổng phần thưởng thu được ở mỗi tập. Ta có thể quan sát rằng:
Biểu đồ bên phải cho thấy số bước thực hiện trong mỗi tập. Ta có thể thấy rằng:
Tổ chức mã thành các hàm
Trong thời gian ngắn, chúng ta đã bao quát khá nhiều nội dung. Giờ hãy lùi lại một bước và tổ chức mọi thứ đã viết. Chúng ta sẽ tạo các hàm cho từng bước đã thực hiện để triển khai SARSA.
Đầu tiên, một hàm tạo môi trường:
Tiếp theo, một hàm khởi tạo Q-table cho một môi trường:
Chiến lược Epsilon-greedy nhận môi trường, Q-table, trạng thái hiện tại và epsilon:
Quy tắc cập nhật của SARSA, yêu cầu Q-table, trạng thái hiện tại, hành động đã thực hiện ở trạng thái đó, phần thưởng cho hành động, trạng thái và hành động tiếp theo:
Cuối cùng, một hàm lớn để huấn luyện tác tử với SARSA, yêu cầu môi trường, số tập chạy, các tham số alpha, gamma và epsilon:
Thêm một hàm để vẽ các chỉ số hiệu năng:
Hàm
create_gif()mà chúng ta đã dùng trước đó:Và một hàm khác để chạy một tập duy nhất kèm kết xuất hình ảnh dùng Q-table đã học hoàn chỉnh (phục vụ tạo hoạt ảnh):
Giờ, hãy thực thi mọi thứ:
Các biểu đồ hiệu năng trông ổn. Giờ hãy xem GIF được tạo:
Tuyệt vời! Taxi đã đón khách đúng ở ô màu xanh dương và trả họ tại ô màu vàng.
Tôi đã dán toàn bộ mã đã tổ chức để triển khai SARSA vào một gist trên GitHub để bạn có thể xem lại bất cứ lúc nào.
Trực giác đằng sau quy tắc cập nhật của SARSA
Trọng tâm của SARSA là quy tắc cập nhật, điều khiển cách tác tử học từ trải nghiệm. Hãy phân tích quy tắc này và khám phá trực giác đằng sau nó:
Q(s, a) = Q(s, a) + α [R + γ Q(s', a') - Q(s, a)]
Hiểu các thành phần
Quá trình học
Quy tắc cập nhật của SARSA nhằm tinh chỉnh sự hiểu biết của tác tử về môi trường bằng cách điều chỉnh Q-value dựa trên trải nghiệm mới. Cách hoạt động như sau:
Sai số sai biệt theo thời gian
Hạng tử [R + γ * Q(s’, a’) — Q(s, a)] được gọi là sai số sai biệt theo thời gian (TD error). Hãy coi nó như thước đo mức độ “ngạc nhiên”:
Sai số này giúp tác tử liên tục tinh chỉnh ước lượng, thúc đẩy quá trình học hướng tới một chính sách tối ưu.
Vai trò của các siêu tham số
1. Tốc độ học (α):
2. Hệ số chiết khấu (γ):
3. Tỷ lệ khám phá (ε):
Bức tranh tổng thể
Quy tắc cập nhật của SARSA cho phép tác tử học từ trải nghiệm bằng cách liên tục điều chỉnh ước lượng giá trị trạng thái–hành động. Với mỗi tương tác, tác tử “khôn” hơn đôi chút về môi trường của mình. Qua nhiều tập, quá trình này dẫn tới việc hình thành một chính sách tối ưu để điều hướng môi trường.
Bằng cách tinh chỉnh các siêu tham số, chúng ta có thể kiểm soát nhiều khía cạnh của quá trình học, cho phép SARSA thích ứng với các loại bài toán và môi trường khác nhau. Tính linh hoạt này, kết hợp với quy tắc cập nhật trực quan, khiến SARSA trở thành một thuật toán học tăng cường mạnh mẽ và được sử dụng rộng rãi.
SARSA so với Q-learning: Khác biệt chính
Dù SARSA và Q-learning đều là các thuật toán học tăng cường được dùng rộng rãi, chúng có một số khác biệt quan trọng. Những khác biệt này then chốt để hiểu khi nào và cách dùng mỗi thuật toán.
1. On-policy so với off-policy
Là một thuật toán on-policy, SARSA học giá trị của chính sách mà nó đang theo, kể cả những bước đi trong lúc khám phá. Q-learning là off-policy; nó học giá trị của chính sách tối ưu — ngay cả khi không theo chính sách đó, nó vẫn học giá trị của chính sách tối ưu khi cuối cùng đến cuối tập. Đó là lý do chúng tôi đã nói từ đầu rằng nên dùng SARSA khi hành trình học quan trọng không kém kết quả. Q-learning thì không mấy bận tâm đến hành trình học.
2. Quy tắc cập nhật
Khác biệt chính là SARSA dùng Q-value của hành động tiếp theo thực sự được thực hiện (a’), trong khi Q-learning dùng Q-value lớn nhất của trạng thái tiếp theo (max(Q(s’, a’))).
3. Cân nhắc việc khám phá
Khi cập nhật Q-value, SARSA không bỏ qua chính sách khám phá nên thận trọng hơn. Ngược lại, Q-learning luôn giả định tác tử sẽ thực hiện hành động tối ưu trong tương lai nên hung hăng hơn.
4. Hội tụ
Dù cả hai cuối cùng đều đạt chính sách tối ưu, Q-learning thường học nhanh hơn, đặc biệt trong môi trường tất định.
5. An toàn
Trong các môi trường mà việc khám phá có thể dẫn đến hậu quả xấu, SARSA thường học các chính sách an toàn hơn vì nó tính đến chính sách thực tế đang được theo.
Trong bài toán “đi dọc vách đá” cổ điển, SARSA thường học một lối đi an toàn hơn, tránh xa mép vực, trong khi Q-learning có thể học lối đi mạo hiểm dọc theo mép.
6. Ổn định
Trong một số môi trường ngẫu nhiên, SARSA có thể ổn định hơn vì nó tính đến hành động tiếp theo thực tế, ngay cả khi đó là hành động thăm dò kém tối ưu.
7. Nhạy cảm với siêu tham số
Q-learning có thể nhạy cảm hơn với lựa chọn tốc độ học và tỷ lệ khám phá, đặc biệt trong môi trường có tính ngẫu nhiên lớn.
8. Ứng dụng thực tế
Với robot hoặc các hệ thống vật lý nơi việc khám phá tốn kém và chúng ta muốn triển khai các chính sách an toàn hơn, có thể ưu tiên thuật toán on-policy SARSA. Khi ở thế giới mô phỏng, trò chơi, hoặc các môi trường có nhiều phản hồi và chúng ta muốn tìm chính sách tối ưu một cách nhanh chóng và tương đối an toàn, Q-learning thường phù hợp hơn.
Vì thế, bạn có thể nghĩ rằng SARSA thuộc “trường phái an toàn”, còn Q-learning là cách tiếp cận nhanh hơn và táo bạo hơn. Trên thực tế, điều này phụ thuộc vào bài toán cụ thể. Cả hai đều rất mạnh, và việc hiểu rõ khác biệt giữa chúng luôn có ý nghĩa.
Kết luận
Trong hướng dẫn toàn diện này, chúng ta đã khám phá thuật toán SARSA, bao gồm khái niệm cốt lõi, chi tiết triển khai và ứng dụng thực tế bằng môi trường Taxi-v3.
Một số điểm chính gồm:
Khả năng học các chính sách an toàn hơn khiến SARSA phù hợp với ứng dụng thực tế nơi chi phí khám phá cao, dù trong một số kịch bản nó có thể hội tụ chậm hơn so với các thuật toán off-policy như Q-learning.
Hãy nhớ rằng việc chọn giữa SARSA và các thuật toán khác phụ thuộc vào bài toán và môi trường cụ thể. Thử nghiệm và tinh chỉnh là chìa khóa để đạt kết quả tối ưu.
Chúng tôi khuyến khích bạn xây dựng thêm trên nền tảng này bằng cách khám phá các môi trường phức tạp hơn, triển khai SARSA với xấp xỉ hàm, hoặc tìm hiểu các thuật toán học tăng cường khác.
Dưới đây là một số tài nguyên liên quan để hỗ trợ bạn: