使用深度 Q 学习解决Lunar lander问题
使用深度 Q 学习解决Lunar lander问题
- 0. 前言
- 1. 使用深度 Q 网络解决 Atari 游戏
- 2. 定义环境
- 3. 解决 Lunar lander 问题
- 相关链接
0. 前言
深度 Q 学习模型只需观察状态作为输入就能够解决经典 Atari
游戏,这是一个重大突破,从那时起,深度强化学习 (deep reinforcement learning
, DRL
) 已经展示出具有比人类更好地解决许多复杂任务的能力。在本节中,我们将实现经典深度 Q 网络 (deep Q-learning
, DQN
) 解决 Lunar lander
问题。
1. 使用深度 Q 网络解决 Atari 游戏
使用深度 Q 网络 (deep Q-learning
, DQN
) 解决经典 Atari
游戏需要大量迭代。即使是基本 Atari
环境,所需的训练回合数也可能达到数百万个。虽然改进的强化学习方法已经降低了训练回合数,但总体而言,度强化学习 (deep reinforcement learning
, DRL
) 是一项计算昂贵的任务。
2. 定义环境
首先,导入所需库,并定义 Gym
环境:
import gym.wrappers
import matplotlib.pyplot as plt
import os
import pickle
import numpy as np
import mediapy
import random
from collections import deque
from livelossplot import PlotLossesENVIRONMENT = "LunarLander-v2" #@param ["CartPole-v1", "Acrobot-v1", "CubeCrash-v0", "MountainCar-v0", "LunarLander-v2"]env = gym.make(ENVIRONMENT, render_mode='rgb_array')state = env.reset()[0]
plt.imshow(env.render())print("action space: {0!r}".format(env.action_space))
print("observation space: {0!r}".format(env.observation_space))ENVIRONMENT = "LunarLander-v2" #@param ["CartPole-v1", "Acrobot-v1", "MountainCar-v0", "LunarLander-v2"]
SIMULATION_RUNS = 10 #@param {type:"slider", min:1, max:10, step:1}
SIMULATION_ITERATIONS = 200 #@param {type:"slider", min:50, max:200, step:1}env = gym.make(ENVIRONMENT, render_mode='rgb_array')fitnesses = []
frames = []for run in range(SIMULATION_RUNS): state = env.reset()state = state[0]fitness = 0for i in range(SIMULATION_ITERATIONS):action = env.action_space.sample()state, reward, done, info, _ = env.step(np.argmax(action)) frames.append(env.render()) fitness += reward if done: fitnesses.append(fitness) break mediapy.show_video(frames, fps=30)
print(fitnesses)
3. 解决 Lunar lander 问题
(1) 定义 DQNAgent
类,init
函数设置了基本的超参数并保存了动作和状态空间的大小,使用 memory
存储模拟的经验以及智能体模型:
import tensorflow.keras as k
import tensorflow.keras.layers as klclass DQNAgent():def __init__(self, state_size, action_size, episodes=100):self.weight_backup = "backup_weights.h5"self.state_size = state_sizeself.action_size = action_sizeself.memory = deque(maxlen=2000)self.learning_rate = 0.001self.gamma = 0.95self.exploration_rate = 1.0self.exploration_min = 0.1self.exploration_decay = (self.exploration_rate-self.exploration_min) / episodes self.brain = self._build_model()
(2) 接下来,在 _build_model()
函数中定义智能体的深度学习模型。创建一个三层模型,将状态空间作为输入,动作空间作为输出,模型使用均方误差 (Mean squared error
, MSE
) 作为损失函数、Adam
作为优化器进行编译,同时模型能够加载先前训练过的模型权重的文件。
def _build_model(self):# Neural Net for Deep-Q learning Modelmodel = k.Sequential()model.add(kl.Dense(24, input_dim=self.state_size, activation='relu'))model.add(kl.Dense(24, activation='relu'))model.add(kl.Dense(self.action_size, activation='linear'))model.compile(loss='mse', optimizer=k.optimizers.Adam(learning_rate=self.learning_rate))if os.path.isfile(self.weight_backup):model.load_weights(self.weight_backup)self.exploration_rate = self.exploration_minreturn model
(3) act()
函数首先评估探索的机会,并根据情况返回随机动作(如果进行探索)或预测的动作(如果不进行探索)。其次,remember()
函数将智能体的经验存储为它模拟的回合,memory
,是一个双端队列类,使用固定大小,在满了之后会自动删除最早的记忆。当记忆足够多时,replay()
函数从智能体的记忆中提取一批经验。然后,这批经验用于重播智能体的动作并评估每个先前执行的动作(随机或预测)的质量,动作的质量目标是使用 Q 学习方程计算的。然后,在单个 epoch
中使用 fit()
函数更新模型。最后,在 replay()
函数结束时,通过 exploration_decay
更新探索率——exploration_rate
:
def save_model(self):self.brain.save(self.weight_backup)def mem_usage(self):return len(self.memory)/2000def act(self, state):if np.random.rand() <= self.exploration_rate:return random.randrange(self.action_size)act_values = self.brain.predict(state)return np.argmax(act_values[0])def remember(self, state, action, reward, next_state, done):self.memory.append((state, action, reward, next_state, done)) def replay(self, batch_size):if len(self.memory) < batch_size:returnsample_batch = random.sample(self.memory, batch_size)for state, action, reward, next_state, done in sample_batch:target = rewardif not done:target = reward + self.gamma * np.amax(self.brain.predict(next_state)[0])target_f = self.brain.predict(state)target_f[0][action] = targetself.brain.fit(state, target_f, epochs=1, verbose=0)if self.exploration_rate > self.exploration_min:self.exploration_rate -= self.exploration_decay
(4) 模型训练代码首先设置 BATCH_SIZE 和 EPISODES
这两个主要超参数。然后,开始循环遍历每个回合的数量,并在每个回合中模拟智能体,直到 env.step
输出 done
值等于 True
。如果智能体尚未完成,将状态输入到 agent.act
函数中以输出动作预测,然后将其应用于 env.step
函数以输出下一个状态、奖励和完成标志。接下来,调用 agent.remember
将动作和结果添加到 memory
中。在每个回合结束时,当 done == True
时,调用 agent.remember
,重播所有动作,并使用结果来训练模型:
BATCH_SIZE = 256 #@param {type:"slider", min:32, max:256, step:2}
EPISODES = 1000 #@param {type:"slider", min:10, max:1000, step:1}
import tqdmstate_size = env.observation_space.shape[0]
action_size = env.action_space.n
agent = DQNAgent(state_size, action_size, episodes=EPISODES)groups = { "reward" : {"total", "max", "avg"}, "agent" : {"explore_rate", "mem_usage"}}
plotlosses = PlotLosses(groups=groups)
total_rewards = 0
for ep in tqdm.tqdm(range(EPISODES)):rewards = []state = env.reset()state = state[0]state = np.reshape(state, [1, state_size])done = Falseindex = 0while not done: action = agent.act(state)next_state, reward, done, info, _ = env.step(action)rewards.append(reward)next_state = np.reshape(next_state, [1, state_size])agent.remember(state, action, reward, next_state, done)state = next_state agent.replay(BATCH_SIZE) total_rewards += sum(rewards)plotlosses.update({'total': sum(rewards),'max': max(rewards),"avg" : total_rewards/(ep+1),"explore_rate" : agent.exploration_rate,"mem_usage" : agent.mem_usage(),})plotlosses.send()
(5) 在 Lunar lander
环境上训练 DQN
智能体 1000
个回合,可以看到智能体逐渐积累奖励,掌握环境:
fitness = 0
frames = []state = env.reset()
state = state[0]
done = False
while not done: state = np.reshape(state, [1, state_size])action = agent.act(state)next_state, reward, done, info, _ = env.step(action) state = next_statefitness += rewardframes.append(env.render())
env.close()print(fitness)
mediapy.show_video(frames, fps=30)
DQN
和 DRL
是人工智能和机器学习的重大进展,展示了数字智能可能比人类更好地解决某些任务的潜力。
相关链接
进化深度学习 (Evolutionary Deep Learning, EDL)
Python 实现生命游戏及进化模拟完整指南
从进化论到代码实现:构建可进化的生命模拟系统
遗传算法 (Genetic Algorithm) 详解与实现
遗传算法核心算子全解析:原理比较与性能评估
Python DEAP 库深度解析:从基础架构到高级应用
使用 DEAP 库实现遗传算法解决 OneMax 问题
使用 DEAP 库实现遗传算法解决 N 皇后问题
使用 DEAP 库实现遗传算法解决旅行商问题
遗传算法重建图像:基于 DEAP 的 EvoLisa 项目复现
基于 DEAP 的遗传编程实战:多变量回归问题求解
基于 DEAP 的粒子群优化实战:复杂方程求解
基于 DEAP 的协同进化实战:波士顿房价预测
基于 DEAP 的进化策略实战:多项式函数逼近
基于 DEAP 的差分进化实战:多项式函数逼近
深度学习中的超参数优化与模型调整策略
神经网络超参数优化:随机搜索完整实现指南
神经网络超参数优化:网格搜索完整实现指南
粒子群优化在自动超参数优化中的应用实现指南
进化策略在自动超参数优化中的应用实现指南
差分搜索在自动超参数优化中的应用实现指南
使用 NumPy 从零实现神经网络:构建与训练多层感知器
神经进化实践:用遗传算法替代反向传播优化神经网络
神经进化实践:使用遗传算法优化 Keras 神经网络
卷积神经网络 (CNN) 原理详解与 Keras 实践
进化卷积神经网络 (EvoCNN) 架构设计:基因编码与 Keras 实现
进化卷积神经网络 (Evolutionary Convolutional Neural Network, EvoCNN) 实战
卷积自编码器 (Convolutional AutoEncoder) 详解与实现
卷积自编码器架构设计:基因编码与 Keras 实现
进化自编码器 (Evolutionary AutoEncoder, EvoAE) 实战
变分自编码器 (Variational AutoEncoder, VAE) 详解与实现
生成对抗网络 (Generative Adversarial Networks, GAN) 详解与实现
WGAN (Wasserstein Generative Adversarial Networks) 详解与实现
WGAN 架构设计:基因编码与 Keras 实现
进化生成对抗网络 (Evolutionary Generative Adversarial Networks, EvoGAN) 实战
NEAT 算法解析:从增强拓扑原理到异或问题实战
NEAT 算法实战:基于进化神经网络的分类问题求解
使用 NEAT 算法实现端到端 MNIST 手写数字识别
NEAT 算法中的物种分化机制与优化实践
深度解析强化学习:原理、算法与实战
使用 NEAT 进化智能体解决 Gymnasium 强化学习环境
NEAT 算法解决 Lunar Lander 问题:从理论到实践