【DRL】深度强化学习介绍

CSDN 2024-10-25 11:31:01 阅读 95

        本篇文章是博主强化学习RL领域学习时,用于个人学习、研究或者欣赏使用,并基于博主对相关等领域的一些理解而记录的学习摘录和笔记,若有不当和侵权之处,指出后将会立即改正,还望谅解。文章强化学习:

       强化学习(2)---《【DRL】深度强化学习介绍》

【DRL】深度强化学习介绍

目录

1 深度Q网络(DQN)

DQN的更新步骤

2 策略梯度方法

REINFORCE算法

演员-评论家(Actor-Critic)

3 深度强化学习的优势与挑战

[Python] 深度Q网络(DQN)实现

[Python] REINFORCE算法实现

[Results] 运行结果

[Notice]  注意事项


        随着深度学习的迅猛发展,深度强化学习(Deep Reinforcement Learning, DRL)将深度学习与强化学习相结合,使得处理高维状态空间成为可能。

1 深度Q网络(DQN)

        深度Q网络使用神经网络来近似Q值函数。DQN引入了经验重放(Experience Replay)和目标网络(Target Network)来提高学习稳定性和效率。

DQN的更新步骤

从经验池中随机抽取一个小批量的经验。更新Q值函数,使用最小化均方误差(MSE)的方法。

[ L = \mathbb{E}_{s,a,r,s'} \left[ \left( y - Q(s,a; \theta) \right)^2 \right] ]

其中

( y = R + \gamma \max_{a'} Q(s', a'; \theta^{-}) )

( \theta^{-} )

是目标网络的参数。

2 策略梯度方法

REINFORCE算法

REINFORCE是一种基于蒙特卡罗方法的策略梯度算法,它通过直接对策略进行参数化来优化期望回报。对于给定状态 ( s ) 和动作 ( a ),更新规则如下:

[ \nabla J(\theta) = \mathbb{E}{\tau \sim \pi\theta} \left[ G_t \nabla \log \pi_\theta(a_t | s_t) \right] ]

其中:

( J(\theta) )

是目标函数,表示期望累计奖励。

( G_t )

是从时间步 ( t ) 开始的回报。

( \pi_\theta(a | s) )

是在状态 ( s ) 下选择动作 ( a ) 的策略。

这种方法的优势在于它可以处理高维的动作空间,但通常收敛速度较慢。

演员-评论家(Actor-Critic)

        演员-评论家方法结合了值函数和策略优化。演员负责生成动作,而评论家则评估这些动作的质量。更新过程同时优化策略和价值估计。

演员更新:通过策略梯度法来调整策略。评论家更新:使用时序差分方法更新值函数。

3 深度强化学习的优势与挑战

        深度强化学习的优势在于能有效处理复杂、高维的状态空间,如图像和语音等。然而,它也面临着一些挑战,例如:

样本效率低:需要大量的交互样本来训练模型。收敛性问题:在某些情况下,可能会出现不稳定或不收敛的问题。超参数调优:需要仔细设置学习率、折扣因子等超参数。


[Python] 深度Q网络(DQN)实现

<code>""" 深度Q网络(DQN)实现

时间:2024.07.27

环境:gym-CartPole-v1

作者:不去幼儿园

"""

import gym

import torch

import torch.nn as nn

import torch.optim as optim

import random

import numpy as np

from collections import deque

# 定义Q网络

class QNetwork(nn.Module):

def __init__(self, state_size, action_size):

super(QNetwork, self).__init__()

# 第一层全连接层,将输入状态映射到64个隐藏单元

self.fc1 = nn.Linear(state_size, 64)

# 第二层全连接层,将64个隐藏单元映射到另一个64个隐藏单元

self.fc2 = nn.Linear(64, 64)

# 输出层,将隐藏单元映射到动作空间的大小

self.fc3 = nn.Linear(64, action_size)

def forward(self, x):

# 前向传播:使用ReLU激活函数

x = torch.relu(self.fc1(x))

x = torch.relu(self.fc2(x))

return self.fc3(x)

# DQN代理

class DQNAgent:

def __init__(self, state_size, action_size):

self.state_size = state_size # 状态空间的大小

self.action_size = action_size # 动作空间的大小

# 初始化Q网络和目标Q网络

self.qnetwork = QNetwork(state_size, action_size)

self.target_qnetwork = QNetwork(state_size, action_size)

# 优化器使用Adam

self.optimizer = optim.Adam(self.qnetwork.parameters(), lr=0.001)

# 经验回放缓冲区,最大长度为2000

self.memory = deque(maxlen=2000)

self.gamma = 0.99 # 折扣因子

self.epsilon = 1.0 # 探索率

self.epsilon_decay = 0.995 # 探索率衰减

self.epsilon_min = 0.01 # 最小探索率

self.batch_size = 64 # 批次大小

self.update_target_every = 5 # 每5次更新目标网络

self.update_count = 0 # 更新计数器

def remember(self, state, action, reward, next_state, done):

# 将经验存储到记忆中

state = np.array(state, dtype=np.float32)

next_state = np.array(next_state, dtype=np.float32)

self.memory.append((state, action, reward, next_state, done))

def act(self, state):

# 使用epsilon-greedy策略选择动作

if np.random.rand() <= self.epsilon:

return random.choice(range(self.action_size)) # 随机选择动作

state = torch.FloatTensor(state).unsqueeze(0)

with torch.no_grad():

q_values = self.qnetwork(state)

return np.argmax(q_values.numpy()) # 选择Q值最大的动作

def replay(self):

# 经验回放

if len(self.memory) < self.batch_size:

return

batch = random.sample(self.memory, self.batch_size)

states, actions, rewards, next_states, dones = zip(*batch)

states = np.array(states, dtype=np.float32)

actions = np.array(actions)

rewards = np.array(rewards, dtype=np.float32)

next_states = np.array(next_states, dtype=np.float32)

dones = np.array(dones, dtype=np.float32)

states = torch.FloatTensor(states)

actions = torch.LongTensor(actions).unsqueeze(1)

rewards = torch.FloatTensor(rewards)

next_states = torch.FloatTensor(next_states)

dones = torch.FloatTensor(dones)

# 计算当前Q值

q_values = self.qnetwork(states).gather(1, actions).squeeze()

# 计算目标Q值

with torch.no_grad():

next_q_values = self.target_qnetwork(next_states).max(1)[0]

targets = rewards + (self.gamma * next_q_values * (1 - dones))

# 计算损失并进行反向传播

loss = nn.MSELoss()(q_values, targets)

self.optimizer.zero_grad()

loss.backward()

self.optimizer.step()

# 更新epsilon

if self.epsilon > self.epsilon_min:

self.epsilon *= self.epsilon_decay

self.update_count += 1

# 更新目标网络

if self.update_count % self.update_target_every == 0:

self.target_qnetwork.load_state_dict(self.qnetwork.state_dict())

# 训练DQN的主函数

def train_dqn(env_name, n_episodes=1000):

env = gym.make(env_name, render_mode="human") # 创建环境并设置渲染模式code>

agent = DQNAgent(env.observation_space.shape[0], env.action_space.n) # 初始化代理

for episode in range(n_episodes):

state, _ = env.reset() # 重置环境并获取初始状态

total_reward = 0

done = False

while not done:

action = agent.act(state) # 根据策略选择动作

step_result = env.step(action) # 执行动作

if len(step_result) == 5: # 如果返回5个值

next_state, reward, done, truncated, _ = step_result

else:

next_state, reward, done, _ = step_result

agent.remember(state, action, reward, next_state, done) # 存储经验

agent.replay() # 经验回放

state = next_state # 更新状态

total_reward += reward

# 每训练100轮显示一次运行界面

if (episode + 1) % 100 == 0:

env.render()

print(f"第 {episode + 1} 轮,总奖励: {total_reward}")

env.close() # 关闭环境

train_dqn('CartPole-v1') # 开始训练

[Python] REINFORCE算法实现

""" REINFORCE算法实现

时间:2024.07.27

环境:gym-CartPole-v1

作者:不去幼儿园

"""

import gym

import torch

import torch.nn as nn

import torch.optim as optim

import numpy as np

# 定义策略网络

class PolicyNetwork(nn.Module):

def __init__(self, state_size, action_size):

super(PolicyNetwork, self).__init__()

self.fc1 = nn.Linear(state_size, 64) # 第一层全连接层

self.fc2 = nn.Linear(64, action_size) # 输出层

def forward(self, x):

x = torch.relu(self.fc1(x)) # 使用ReLU激活函数

return torch.softmax(self.fc2(x), dim=-1) # 使用Softmax输出概率分布

# REINFORCE代理

class REINFORCEAgent:

def __init__(self, state_size, action_size):

self.policy_network = PolicyNetwork(state_size, action_size) # 初始化策略网络

self.optimizer = optim.Adam(self.policy_network.parameters(), lr=0.001) # 使用Adam优化器

self.gamma = 0.99 # 折扣因子

def select_action(self, state):

state = torch.FloatTensor(state).unsqueeze(0) # 转换状态为张量,并增加一个维度

probs = self.policy_network(state) # 获取动作概率

action = np.random.choice(len(probs[0]), p=probs.detach().numpy()[0]) # 根据概率选择动作

return action, torch.log(probs[0, action]) # 返回动作和对应的对数概率

def update_policy(self, rewards, log_probs):

discounted_rewards = [] # 初始化折扣奖励列表

R = 0 # 初始化累计奖励

for r in reversed(rewards): # 计算折扣奖励

R = r + self.gamma * R

discounted_rewards.insert(0, R) # 插入到列表的开头

discounted_rewards = torch.FloatTensor(discounted_rewards) # 转换为张量

# 标准化奖励

discounted_rewards = (discounted_rewards - discounted_rewards.mean()) / (discounted_rewards.std() + 1e-9)

log_probs = torch.stack(log_probs) # 将对数概率堆叠成一个张量

loss = -torch.sum(log_probs * discounted_rewards) # 计算损失

self.optimizer.zero_grad() # 清零梯度

loss.backward() # 反向传播

self.optimizer.step() # 更新参数

# 训练REINFORCE的主函数

def train_reinforce(env_name, n_episodes=1000):

render = False # 初始化渲染标志为False

for episode in range(n_episodes):

if (episode + 1) % 100 == 0: # 每训练100轮设置渲染标志为True

render = True

else:

render = False

# 创建环境,并根据渲染标志设置渲染模式

env = gym.make(env_name, render_mode="human" if render else None)code>

agent = REINFORCEAgent(env.observation_space.shape[0], env.action_space.n) # 初始化代理

state, _ = env.reset() # 重置环境并获取初始状态

log_probs = [] # 初始化对数概率列表

rewards = [] # 初始化奖励列表

total_reward = 0 # 初始化总奖励

done = False # 初始化完成标志为False

while not done:

if render:

env.render() # 如果渲染标志为True,渲染环境

action, log_prob = agent.select_action(state) # 选择动作

next_state, reward, done, truncated, _ = env.step(action) # 执行动作

log_probs.append(log_prob) # 存储对数概率

rewards.append(reward) # 存储奖励

state = next_state # 更新状态

total_reward += reward # 更新总奖励

agent.update_policy(rewards, log_probs) # 更新策略

print(f"第 {episode + 1} 轮,总奖励: {total_reward}") # 输出本集总奖励

if render:

env.close() # 如果渲染标志为True,关闭环境

train_reinforce('CartPole-v1') # 开始训练


[Results] 运行结果


[Notice]  注意事项

深度Q网络(DQN)实现注释说明:

<code>import 部分:导入所需的库,包括 gym(用于环境模拟)、torch(用于深度学习)、random 和 numpy(用于随机数生成和数值计算)、deque(用于经验回放缓冲区)。QNetwork 类:定义了Q网络的结构,包括输入层、隐藏层和输出层。DQNAgent 类:定义了DQN智能体,包括初始化、存储经验、选择动作和经验回放等方法。train_dqn 函数:主训练循环,包括环境交互、经验存储和训练。

 REINFORCE算法实现详细注释说明:

导入库

gym:用于创建和管理强化学习环境。torch 和 torch.nn:用于构建和训练神经网络。torch.optim:用于优化神经网络参数。numpy:用于数值计算和数组操作。

PolicyNetwork

定义了一个两层全连接的神经网络,输出动作的概率分布。使用ReLU激活函数和Softmax输出层。

REINFORCEAgent

初始化策略网络和优化器。select_action 方法基于策略网络输出的概率分布选择动作,并返回该动作和对应的对数概率。update_policy 方法计算每个步骤的折扣奖励,并使用标准化后的折扣奖励更新策略网络的参数。

train_reinforce 函数

初始化渲染标志 render。每训练100轮设置渲染标志为True。创建环境时,根据渲染标志设置 render_mode 为 "human" 或 None。在每一步中选择动作,执行动作,存储对数概率和奖励,更新状态,并在需要时渲染环境。在每个回合结束时,调用 update_policy 更新策略网络。在渲染标志为True时,关闭环境以等待下次再打开。


     文章若有不当和不正确之处,还望理解与指出。由于部分文字、图片等来源于互联网,无法核实真实出处,如涉及相关争议,请联系博主删除。如有错误、疑问和侵权,欢迎评论留言联系作者,或者关注VX公众号:Rain21321,联系作者。



声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。