深度强化学习中的蒙特卡洛方法详解
蒙特卡洛方法概述
蒙特卡洛(Monte Carlo)方法是强化学习中的一类重要算法,它通过从完整经验片段中采样来学习价值函数和最优策略。与动态规划方法不同,蒙特卡洛方法不需要环境的完整模型,而是直接从经验中学习。
环境设置:Blackjack游戏
在开始实现蒙特卡洛算法前,我们需要先了解Blackjack(21点)游戏环境:
import gym
env = gym.make('Blackjack-v0')
Blackjack环境的状态空间是一个三元组:
- 玩家当前手牌总和(0-31)
- 庄家明牌(1-10)
- 玩家是否有可用的Ace(0表示无,1表示有)
动作空间包含两个动作:
- STICK(停止要牌,值为0)
- HIT(继续要牌,值为1)
蒙特卡洛预测实现
蒙特卡洛预测用于估计给定策略下的状态-动作价值函数(Q函数)。我们首先定义一个随机策略:
def generate_episode_from_limit_stochastic(bj_env):
episode = []
state = bj_env.reset()
while True:
# 手牌总和>18时有80%概率停止要牌
probs = [0.8, 0.2] if state[0] > 18 else [0.2, 0.8]
action = np.random.choice(np.arange(2), p=probs)
next_state, reward, done, info = bj_env.step(action)
episode.append((state, action, reward))
state = next_state
if done:
break
return episode
接下来实现蒙特卡洛预测算法:
def mc_prediction_q(env, num_episodes, generate_episode, gamma=1.0):
returns_sum = defaultdict(lambda: np.zeros(env.action_space.n))
N = defaultdict(lambda: np.zeros(env.action_space.n))
Q = defaultdict(lambda: np.zeros(env.action_space.n))
for i_episode in range(1, num_episodes+1):
if i_episode % 1000 == 0:
print("\rEpisode {}/{}.".format(i_episode, num_episodes), end="")
sys.stdout.flush()
episode = generate_episode(env)
states, actions, rewards = zip(*episode)
# 计算折扣回报
discounts = np.array([gamma**i for i in range(len(rewards)+1)])
# 更新Q值
for i, state in enumerate(states):
action = actions[i]
G = sum(rewards[i:] * discounts[:-(1+i)])
returns_sum[state][action] += G
N[state][action] += 1.0
Q[state][action] = returns_sum[state][action] / N[state][action]
return Q
蒙特卡洛控制实现
蒙特卡洛控制用于找到最优策略,我们实现一个带有ε-贪婪探索的算法:
def mc_control(env, num_episodes, alpha, gamma=1.0, eps_start=1.0, eps_decay=0.99999, eps_min=0.05):
nA = env.action_space.n
Q = defaultdict(lambda: np.zeros(nA))
epsilon = eps_start
for i_episode in range(1, num_episodes+1):
if i_episode % 1000 == 0:
print("\rEpisode {}/{}.".format(i_episode, num_episodes), end="")
sys.stdout.flush()
# 衰减ε值
epsilon = max(epsilon*eps_decay, eps_min)
# 生成一个episode
episode = []
state = env.reset()
while True:
# ε-贪婪策略选择动作
if np.random.random() > epsilon:
action = np.argmax(Q[state])
else:
action = np.random.choice(np.arange(nA))
next_state, reward, done, _ = env.step(action)
episode.append((state, action, reward))
if done:
break
state = next_state
# 更新Q值
states, actions, rewards = zip(*episode)
discounts = np.array([gamma**i for i in range(len(rewards)+1)])
for i, state in enumerate(states):
action = actions[i]
G = sum(rewards[i:] * discounts[:-(1+i)])
Q[state][action] += alpha * (G - Q[state][action])
# 根据Q值确定最优策略
policy = dict((k, np.argmax(v)) for k, v in Q.items())
return policy, Q
结果分析与可视化
运行蒙特卡洛控制算法后,我们可以可视化状态价值函数和最优策略:
# 运行算法
policy, Q = mc_control(env, 500000, 0.02)
# 可视化状态价值函数
V = dict((k, np.max(v)) for k, v in Q.items())
plot_blackjack_values(V)
# 可视化策略
plot_policy(policy)
算法优化建议
-
ε衰减策略:调整ε的初始值和衰减率可以平衡探索与利用。较慢的衰减允许更多探索,但收敛速度可能变慢。
-
学习率α:适当的学习率对收敛至关重要。可以考虑使用自适应学习率或逐步衰减的学习率。
-
批量更新:可以考虑使用批量蒙特卡洛方法,积累多个episode后再统一更新,减少方差。
-
重要性采样:对于非策略学习,可以引入重要性采样比率来提高样本效率。
蒙特卡洛方法特别适用于环境模型未知的强化学习问题,通过直接从经验中学习,可以有效地找到最优策略。理解这些基础算法对于掌握更复杂的深度强化学习方法至关重要。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考