強(qiáng)化學(xué)習(xí)強(qiáng)在哪里?基礎(chǔ)探索
強(qiáng)化學(xué)習(xí)代表了我們對(duì)人工智能思考方式的深刻轉(zhuǎn)變——從僅僅識(shí)別模式的系統(tǒng),轉(zhuǎn)變?yōu)橥ㄟ^(guò)交互學(xué)習(xí)并通過(guò)經(jīng)驗(yàn)改進(jìn)的智能體。正如我們將在本系列中看到的,這種范式正在推動(dòng)當(dāng)今一些最令人印象深刻的人工智能成就,并開(kāi)辟機(jī)器學(xué)習(xí)研究的新前沿。
強(qiáng)化學(xué)習(xí)的基礎(chǔ)
擊敗圍棋世界冠軍的算法可不只是按程序設(shè)定運(yùn)行,它還會(huì)學(xué)習(xí)。在復(fù)雜城市環(huán)境中自動(dòng)駕駛的汽車,并非遵循著明確指令,而是在不斷適應(yīng)。重塑我們數(shù)字體驗(yàn)的突破性語(yǔ)言模型,也不只是在靜態(tài)數(shù)據(jù)上進(jìn)行訓(xùn)練,還通過(guò)交互不斷優(yōu)化。
超越傳統(tǒng)學(xué)習(xí):強(qiáng)化學(xué)習(xí)范式
機(jī)器學(xué)習(xí)傳統(tǒng)上分為兩個(gè)常見(jiàn)類別:監(jiān)督學(xué)習(xí)(從有標(biāo)記的示例中學(xué)習(xí))和無(wú)監(jiān)督學(xué)習(xí)(在無(wú)標(biāo)記的數(shù)據(jù)中尋找模式)。強(qiáng)化學(xué)習(xí)則代表了一種根本不同的方法。
在強(qiáng)化學(xué)習(xí)中,智能體通過(guò)與環(huán)境互動(dòng)來(lái)學(xué)習(xí),根據(jù)其采取的行動(dòng)獲得獎(jiǎng)勵(lì)或懲罰。這里沒(méi)有預(yù)先標(biāo)記的示例,也沒(méi)有靜態(tài)數(shù)據(jù)集,只有動(dòng)態(tài)反饋引導(dǎo)智能體趨向最優(yōu)行為。
這種范式轉(zhuǎn)變反映了人類學(xué)習(xí)復(fù)雜行為的實(shí)際方式:通過(guò)試錯(cuò)、在反饋的引導(dǎo)下并受目標(biāo)驅(qū)動(dòng)。
強(qiáng)化學(xué)習(xí)的核心組件
要理解強(qiáng)化學(xué)習(xí),我們需要拆解其基本組件:
- 智能體:學(xué)習(xí)者或決策者。
- 環(huán)境:智能體與之互動(dòng)的系統(tǒng)。
- 狀態(tài):當(dāng)前的情況或配置。
- 行動(dòng):智能體可以采取的行為。
- 獎(jiǎng)勵(lì):評(píng)估行動(dòng)的反饋信號(hào)。
- 策略:智能體選擇行動(dòng)的策略。
這些元素之間的相互作用形成了一個(gè)持續(xù)的循環(huán):智能體觀察當(dāng)前狀態(tài),根據(jù)其策略采取行動(dòng),獲得獎(jiǎng)勵(lì),并轉(zhuǎn)移到新的狀態(tài)。這個(gè)循環(huán)不斷重復(fù),智能體不斷優(yōu)化其策略以最大化累積獎(jiǎng)勵(lì)。

強(qiáng)化學(xué)習(xí)與其他范式的區(qū)別在于探索(嘗試新行動(dòng)以發(fā)現(xiàn)其結(jié)果)和利用(利用已知的獎(jiǎng)勵(lì))之間的關(guān)鍵相互作用。這種基本的矛盾——探索 - 利用困境,是強(qiáng)化學(xué)習(xí)獨(dú)特挑戰(zhàn)的核心。
神奇背后的數(shù)學(xué):馬爾可夫決策過(guò)程

探索 - 利用困境:深入探究
也許強(qiáng)化學(xué)習(xí)中最引人入勝的挑戰(zhàn)是平衡探索和利用。這不僅僅是一個(gè)技術(shù)問(wèn)題,而是一個(gè)在各個(gè)領(lǐng)域都存在的基本困境:
- 利用:選擇已知能產(chǎn)生高獎(jiǎng)勵(lì)的行動(dòng)。
- 探索:嘗試新行動(dòng),有可能發(fā)現(xiàn)更好的策略。
考慮一個(gè)選擇餐廳的類比:你是回到一家你知道自己喜歡的餐廳(利用),還是嘗試一家可能更好的新餐廳(探索)?無(wú)論選擇哪一個(gè)方向出錯(cuò),你要么錯(cuò)過(guò)發(fā)現(xiàn)更好餐廳的機(jī)會(huì),要么浪費(fèi)一次保證有良好體驗(yàn)的機(jī)會(huì)。
在強(qiáng)化學(xué)習(xí)中,這種困境體現(xiàn)在各種方法中:

簡(jiǎn)單的老虎機(jī)問(wèn)題:你的第一個(gè)強(qiáng)化學(xué)習(xí)實(shí)現(xiàn)
強(qiáng)化學(xué)習(xí)(RL)乍一看可能很復(fù)雜,但我們可以通過(guò)一個(gè)經(jīng)典問(wèn)題來(lái)開(kāi)始理解它:多臂老虎機(jī)問(wèn)題。讓我們以一種更容易可視化和理解的方式來(lái)拆解它。
什么是多臂老虎機(jī)問(wèn)題?
想象你在一家賭場(chǎng),里面有多個(gè)老虎機(jī)(也叫 “臂”)。每臺(tái)老虎機(jī)都有自己隱藏的給予獎(jiǎng)勵(lì)的概率。你的目標(biāo)很簡(jiǎn)單:盡可能多贏錢(qián)。但有個(gè)難題——你不知道哪臺(tái)機(jī)器的 payouts 比其他的更好。你需要通過(guò)試錯(cuò)來(lái)弄清楚。
這就產(chǎn)生了我們所說(shuō)的 “探索與利用困境”:
- 探索:嘗試不同的老虎機(jī),了解哪臺(tái)更好。
- 利用:堅(jiān)持使用你目前認(rèn)為最好的老虎機(jī)。
逐步理解我們的實(shí)現(xiàn)
讓我們逐步構(gòu)建解決方案:
import numpy as np
import matplotlib.pyplot as plt
class MultiArmedBandit:
def __init__(self, n_arms=10):
self.true_rewards = np.random.normal(0, 1, n_arms)
self.n_arms = n_arms
print("每臺(tái)老虎機(jī)的真實(shí)獎(jiǎng)勵(lì)值(智能體未知):", self.true_rewards)
print("最優(yōu)的老虎機(jī)是 #", np.argmax(self.true_rewards), ",預(yù)期獎(jiǎng)勵(lì)為",
np.max(self.true_rewards))
def pull(self, arm):
return np.random.normal(self.true_rewards[arm], 1)
class EpsilonGreedyAgent:
def __init__(self, n_arms=10, epsilon=0.1, learning_rate=0.1):
self.n_arms = n_arms
self.epsilon = epsilon
self.learning_rate = learning_rate
self.q_values = np.zeros(n_arms)
self.arm_counts = np.zeros(n_arms)
def select_action(self):
if np.random.random() < self.epsilon:
return np.random.randint(self.n_arms)
else:
return np.argmax(self.q_values)
def update(self, arm, reward):
self.arm_counts[arm] += 1
self.q_values[arm] += self.learning_rate * (reward - self.q_values[arm])
def run_bandit_experiment(n_arms=10, n_steps=1000, epsilon=0.1, learning_rate=0.1, random_seed=42):
np.random.seed(random_seed)
bandit = MultiArmedBandit(n_arms)
agent = EpsilonGreedyAgent(n_arms, epsilon=epsilon, learning_rate=learning_rate)
rewards = np.zeros(n_steps)
optimal_actions = np.zeros(n_steps)
optimal_arm = np.argmax(bandit.true_rewards)
for step in range(n_steps):
arm = agent.select_action()
optimal_actions[step] = 1 if arm == optimal_arm else 0
reward = bandit.pull(arm)
rewards[step] = reward
agent.update(arm, reward)
cumulative_average_reward = np.cumsum(rewards) / (np.arange(n_steps) + 1)
optimal_action_percentage = np.cumsum(optimal_actions) / (np.arange(n_steps) + 1)
return {
'rewards': rewards,
'cumulative_average_reward': cumulative_average_reward,
'optimal_action_percentage': optimal_action_percentage,
'agent': agent,
'bandit': bandit,
'optimal_arm': optimal_arm
}
def visualize_results(results):
plt.figure(figsize=(12, 10))
plt.subplot(2, 1, 1)
plt.plot(results['cumulative_average_reward'])
plt.xlabel('步驟')
plt.ylabel('平均獎(jiǎng)勵(lì)')
plt.title('隨時(shí)間的平均獎(jiǎng)勵(lì)')
plt.grid(True, alpha=0.3)
plt.subplot(2, 1, 2)
plt.plot(results['optimal_action_percentage'])
plt.xlabel('步驟')
plt.ylabel('最優(yōu)行動(dòng)百分比')
plt.title('選擇最優(yōu)行動(dòng)的頻率')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
print("\n最終結(jié)果:")
print(f"智能體對(duì)每臺(tái)老虎機(jī)的最終價(jià)值估計(jì): {results['agent'].q_values.round(3)}")
print(f"真實(shí)獎(jiǎng)勵(lì)值: {results['bandit'].true_rewards.round(3)}")
print(f"最優(yōu)老虎機(jī): {results['optimal_arm']}")
print(f"每臺(tái)老虎機(jī)被拉動(dòng)的次數(shù): {results['agent'].arm_counts.astype(int)}")
plt.figure(figsize=(10, 5))
plt.bar(range(len(results['agent'].arm_counts)), results['agent'].arm_counts)
plt.xlabel('老虎機(jī)')
plt.ylabel('拉動(dòng)次數(shù)')
plt.title('老虎機(jī)選擇分布')
plt.show()
results = run_bandit_experiment(n_arms=10, n_steps=1000, epsilon=0.1)
visualize_results(results)
def compare_epsilons():
epsilons = [0.01, 0.1, 0.5]
plt.figure(figsize=(15, 6))
for i, epsilon in enumerate(epsilons):
results = run_bandit_experiment(epsilon=epsilon, random_seed=42)
plt.subplot(1, 2, 1)
plt.plot(results['cumulative_average_reward'], label=f'ε={epsilon}')
plt.subplot(1, 2, 2)
plt.plot(results['optimal_action_percentage'], label=f'ε={epsilon}')
plt.subplot(1, 2, 1)
plt.xlabel('步驟')
plt.ylabel('平均獎(jiǎng)勵(lì)')
plt.title('隨時(shí)間的平均獎(jiǎng)勵(lì)')
plt.legend()
plt.grid(True, alpha=0.3)
plt.subplot(1, 2, 2)
plt.xlabel('步驟')
plt.ylabel('最優(yōu)行動(dòng)百分比')
plt.title('最優(yōu)行動(dòng)頻率')
plt.legend()
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()智能體通過(guò)經(jīng)驗(yàn)逐漸改進(jìn)其獎(jiǎng)勵(lì)估計(jì),這通過(guò)兩個(gè)關(guān)鍵可視化得以展示:隨時(shí)間的平均獎(jiǎng)勵(lì)和最優(yōu)行動(dòng)頻率。這優(yōu)雅地展示了強(qiáng)化學(xué)習(xí)智能體如何通過(guò)與不確定環(huán)境的直接互動(dòng)發(fā)現(xiàn)最優(yōu)策略。

拆解代碼和概念
- 環(huán)境:我們的一排老虎機(jī)
在代碼中,我們首先創(chuàng)建了??MultiArmedBandit?? 類,它代表我們的一排老虎機(jī)。每臺(tái)老虎機(jī)都有一個(gè)智能體不知道的隱藏 “真實(shí)獎(jiǎng)勵(lì)” 值。
class MultiArmedBandit:
def __init__(self, n_arms=10):
self.true_rewards = np.random.normal(0, 1, n_arms)
self.n_arms = n_arms想象每臺(tái)老虎機(jī)都有自己的 “個(gè)性”:有些很慷慨(正獎(jiǎng)勵(lì)值),有些很吝嗇(負(fù)獎(jiǎng)勵(lì)值)。我們使用正態(tài)分布,所以大多數(shù)老虎機(jī)是中等水平,有少數(shù)非常好或非常差的。當(dāng)我們拉動(dòng)拉桿(臂)時(shí),我們根據(jù)那臺(tái)機(jī)器的真實(shí)值加上一些隨機(jī)噪聲獲得獎(jiǎng)勵(lì):
def pull(self, arm):
return np.random.normal(self.true_rewards[arm], 1)噪聲使學(xué)習(xí)變得更困難——僅僅因?yàn)橐慌_(tái)機(jī)器一次支付豐厚并不意味著它實(shí)際上是整體最好的機(jī)器!
2. 智能體:我們的賭場(chǎng)玩家
??EpsilonGreedyAgent?? 類代表試圖最大化獎(jiǎng)勵(lì)的玩家:
class EpsilonGreedyAgent:
def __init__(self, n_arms=10, epsilnotallow=0.1, learning_rate=0.1):
self.epsilon = epsilon
self.q_values = np.zeros(n_arms)智能體一開(kāi)始一無(wú)所知(所有估計(jì)值為零),必須通過(guò)試錯(cuò)學(xué)習(xí)。關(guān)鍵參數(shù)是 ,它控制智能體探索與利用的頻率:
def select_action(self):
if np.random.random() < self.epsilon:
return np.random.randint(self.n_arms)
else:
return np.argmax(self.q_values)每次拉動(dòng)后,智能體更新其對(duì)該臂價(jià)值的估計(jì):
def update(self, arm, reward):
self.arm_counts[arm] += 1
self.q_values[arm] += self.learning_rate * (reward - self.q_values[arm])這個(gè)更新規(guī)則是許多強(qiáng)化學(xué)習(xí)算法使用的簡(jiǎn)化版本。它的意思是:“根據(jù)新信息的方向稍微調(diào)整你的估計(jì)。”
3. 實(shí)驗(yàn):隨時(shí)間學(xué)習(xí)
主要實(shí)驗(yàn)運(yùn)行許多步驟,智能體選擇臂、接收獎(jiǎng)勵(lì)并更新其知識(shí):
for step in range(n_steps):
arm = agent.select_action()
reward = bandit.pull(arm)
agent.update(arm, reward)我們跟蹤:
- 每一步收到的獎(jiǎng)勵(lì)。
- 智能體是否選擇了最優(yōu)臂(真實(shí)獎(jiǎng)勵(lì)最高的臂)。
4.結(jié)果:我們學(xué)到了什么?
智能體通過(guò)試錯(cuò)逐漸了解哪些臂更好。我們用兩個(gè)關(guān)鍵圖可視化這個(gè)學(xué)習(xí)過(guò)程:
- 隨時(shí)間的平均獎(jiǎng)勵(lì):顯示智能體在學(xué)習(xí)過(guò)程中是否獲得了更好的獎(jiǎng)勵(lì)。
- 最優(yōu)行動(dòng)百分比:顯示智能體選擇真正最佳臂的頻率。
核心強(qiáng)化學(xué)習(xí)循環(huán)
這個(gè)簡(jiǎn)單的例子展示了強(qiáng)化學(xué)習(xí)的基本循環(huán):
- 觀察:智能體觀察當(dāng)前狀態(tài)(在這種情況下,只知道有哪些臂可用)。
- 行動(dòng):智能體選擇一個(gè)行動(dòng)(拉哪條臂)。
- 接收獎(jiǎng)勵(lì):環(huán)境給出反饋(拉臂獲得的獎(jiǎng)勵(lì))。
- 學(xué)習(xí):智能體更新其對(duì)世界的理解。
超越老虎機(jī):構(gòu)建實(shí)際應(yīng)用
雖然多臂老虎機(jī)提供了一個(gè)易于理解的切入點(diǎn),但現(xiàn)實(shí)世界的強(qiáng)化學(xué)習(xí)應(yīng)用要處理復(fù)雜得多的場(chǎng)景:龐大的狀態(tài)空間、延遲的獎(jiǎng)勵(lì)和部分可觀測(cè)的環(huán)境。
想想DeepMind的AlphaGo:狀態(tài)空間包括所有可能的圍棋棋盤(pán)配置(比可觀測(cè)宇宙中的原子數(shù)量還多)。獎(jiǎng)勵(lì)嚴(yán)重延遲(只有在游戲結(jié)束時(shí)才收到)。早期行動(dòng)與最終結(jié)果之間的聯(lián)系極其復(fù)雜。
然而基本原理仍然相同:智能體與環(huán)境互動(dòng),接收獎(jiǎng)勵(lì),并學(xué)習(xí)一種策略以最大化累積獎(jiǎng)勵(lì)。
挑戰(zhàn)與局限
盡管強(qiáng)化學(xué)習(xí)在概念上很優(yōu)雅,但它面臨著重大挑戰(zhàn):
- 樣本效率:強(qiáng)化學(xué)習(xí)算法通常需要與環(huán)境進(jìn)行大量交互才能有效學(xué)習(xí)。
- 穩(wěn)定性:學(xué)習(xí)過(guò)程可能不穩(wěn)定,超參數(shù)的微小變化可能導(dǎo)致截然不同的結(jié)果。
- 獎(jiǎng)勵(lì)設(shè)計(jì):設(shè)計(jì)真正捕捉所需行為的獎(jiǎng)勵(lì)函數(shù)出奇地困難。
- 泛化能力:智能體通常難以將在一個(gè)環(huán)境中學(xué)到的知識(shí)轉(zhuǎn)移到另一個(gè)環(huán)境中。
這些挑戰(zhàn)代表了活躍的研究前沿,最近基于模型的方法、離策略學(xué)習(xí)和分層強(qiáng)化學(xué)習(xí)的進(jìn)展解決了許多這些局限性。
本文轉(zhuǎn)載自??柏企閱文??,作者:柏企

















