强化学习之DQN(deep Q-network)算法

一、简介

DQN算法是深度学习领域首次广泛应用于强化学习的算法模型之一。它于2013年由DeepMind公司的研究团队提出,通过将深度神经网络与经典的强化学习算法Q-learning结合,实现了对高维、连续状态空间的处理,具备了学习与规划的能力。

二、发展史

DQN算法提出之前,强化学习中的经典算法主要是基于表格的Q学习算法。这些算法在处理简单的低维问题时表现出色,但随着状态和动作空间的增加,表格表示的存储和计算复杂度呈指数级增长。为了解决这个问题,研究人员开始探索使用函数逼近的方法,即使用参数化的函数代替表格。

之后,逐步发展出了一系列将深度学习应用于强化学习的算法。DQN算法是其中的一种。它是由Alex Krizhevsky等人在2013年提出的,是首个将深度学习与强化学习相结合的算法。DQN算法引入了经验回放固定Q目标网络等技术,极大地提升了深度神经网络在强化学习中的性能。随后,DQN算法在Atari游戏中取得了比人类玩家更好的成绩,引起了广泛的关注和研究。

Q-learning:Q-learning是强化学习中的经典算法,由Watkins等人在1989年提出。它使用一个Q表格来存储状态和动作的价值,通过不断更新和探索来学习最优策略。然而,Q-learning算法在面对大规模状态空间时,无法扩展。

Deep Q-Network(DQN):DQN算法在2013年由DeepMind团队提出,通过使用深度神经网络来逼近Q函数的值,解决了状态空间规模大的问题。该算法采用了两个关键技术:经验回放和固定Q目标网络。

经验回放:经验回放是DQN算法的核心思想之一,它的基本原理是将智能体的经验存储在一个回放记忆库中,然后随机从中抽样,利用这些经验进行模型更新。这样做的好处是避免了样本间的相关性,提高了模型的稳定性和收敛速度。

固定Q目标网络:DQN算法使用两个神经网络,一个是主网络(online network),用于选择动作,并进行模型更新;另一个是目标网络(target network),用于计算目标Q值。目标网络的参数固定一段时间,这样可以减少目标的波动,提高模型的稳定性。

三、算法公式

本质:Q-learning+深度神经网络 = DQN

3.1 Q-learning算法公式

在这里插入图片描述

Q-learning算法通过不断更新Q值来学习最优策略,其更新公式如下:

在这里插入图片描述

3.2 DQN算法公式:

在这里插入图片描述
在这里插入图片描述

DQN算法通过最小化Q函数的均方差损失来进行模型更新。其更新公式如下:
在这里插入图片描述

四、算法原理

DQN算法的原理是通过利用深度神经网络逼近Q函数的值,实现对高维、连续状态空间的处理。其核心思想是通过不断更新神经网络的参数,使其的输出Q值逼近真实的Q值,从而学习最优策略。

DQN算法的工作原理如下:

初始化:初始化主网络和目标网络的参数。

选择动作:根据当前状态s,使用ε-greedy策略选择动作a。

执行动作并观察回报:采取动作a,与环境交互,观察下一个状态s’和立即回报r。

存储经验:将(s, a, r, s’)存储到经验回放记忆库中。

从经验回放记忆库中随机抽样:从记忆库中随机抽样一批经验。

计算目标Q值:使用目标网络计算目标Q值,即max(Q(s’, a, θ-))。

更新主网络:根据损失函数L(θ)进行模型参数更新。

更新目标网络:定期更新目标网络的参数。

重复步骤2-8,直到达到终止条件。

五、算法功能

DQN算法具有以下功能:

处理高维、连续状态空间:通过深度神经网络的逼近能力,可以处理高维、连续状态空间的问题。

学习和规划能力:通过与环境的交互和不断试错,DQN算法可以学习到最优策略,并具备一定的规划能力。

稳定性和收敛速度高:DQN算法通过经验回放和固定Q目标网络等技术,提高了模型的稳定性和收敛速度。

六、示例代码

以下是一个使用DQN算法解决经典的CartPole问题的示例代码:

# -*- coding: utf-8 -*-
import gym
import numpy as np
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
from tensorflow.keras.optimizers import Adam

env = gym.make('CartPole-v0')
n_actions = env.action_space.n
n_states = env.observation_space.shape[0]

def create_dqn_model():
    model = Sequential()
    model.add(Dense(32, input_shape=(n_states,), activation='relu'))
    model.add(Dense(32, activation='relu'))
    model.add(Dense(n_actions, activation='linear'))
    model.compile(loss='mse', optimizer=Adam(lr=0.001))
    return model

def choose_action(state, epsilon):
    if np.random.rand() < epsilon:
        return np.random.choice(n_actions)
    else:
        q_values = model.predict(state)
        return np.argmax(q_values[0])

def train_dqn():
    epsilon = 1.0
    epsilon_min = 0.01
    epsilon_decay = 0.995
    batch_size = 32
    replay_memory = []
    for episode in range(500):
        state = env.reset()
        state = np.reshape(state, [1, n_states])
        done = False
        steps = 0

        while not done:
            env.render()
            action = choose_action(state, epsilon)
            next_state, reward, done, _ = env.step(action)
            next_state = np.reshape(next_state, [1, n_states])
            replay_memory.append((state, action, reward, next_state, done))
            state = next_state
            steps += 1

            if done:
                print("Episode: %d, Steps: %d" % (episode, steps))
                break
            if len(replay_memory) > batch_size:
                minibatch = np.random.choice(replay_memory, batch_size, replace=False)
                states_mb = np.concatenate([mb[0] for mb in minibatch])
                actions_mb = np.array([mb[1] for mb in minibatch])
                rewards_mb = np.array([mb[2] for mb in minibatch])
                next_states_mb = np.concatenate([mb[3] for mb in minibatch])
                dones_mb = np.array([mb[4] for mb in minibatch])

                targets = rewards_mb + 0.99 * (np.amax(model.predict_on_batch(next_states_mb), axis=1)) * (1 - dones_mb)
                targets_full = model.predict_on_batch(states_mb)
                ind = np.array([i for i in range(batch_size)])
                targets_full[[ind], [actions_mb]] = targets

                model.fit(states_mb, targets_full, epochs=1, verbose=0)

            if epsilon > epsilon_min:
                epsilon *= epsilon_decay

    env.close()

if __name__ == '__main__':

    model = create_dqn_model()

    train_dqn()

参考:

https://www.ngui.cc/el/2433927.html?action=onClick
https://blog.csdn.net/Zhang_0702_China/article/details/123423637
https://www.jb51.net/article/231665.htm
http://lihuaxi.xjx100.cn/news/1290031.html?action=onClick

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
DQNDeep Q-Network)是一种使用深度神经网络实现的强化学习算法,用于解决离散动作空间的问题。在PyTorch中实现DQN可以分为以下几个步骤: 1. 定义神经网络:使用PyTorch定义一个包含多个全连接层的神经网络,输入为状态空间的维度,输出为动作空间的维度。 ```python import torch.nn as nn import torch.nn.functional as F class QNet(nn.Module): def __init__(self, state_dim, action_dim): super(QNet, self).__init__() self.fc1 = nn.Linear(state_dim, 64) self.fc2 = nn.Linear(64, 64) self.fc3 = nn.Linear(64, action_dim) def forward(self, x): x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x ``` 2. 定义经验回放缓存:包含多条经验,每条经验包含一个状态、一个动作、一个奖励和下一个状态。 ```python import random class ReplayBuffer(object): def __init__(self, max_size): self.buffer = [] self.max_size = max_size def push(self, state, action, reward, next_state): if len(self.buffer) < self.max_size: self.buffer.append((state, action, reward, next_state)) else: self.buffer.pop(0) self.buffer.append((state, action, reward, next_state)) def sample(self, batch_size): state, action, reward, next_state = zip(*random.sample(self.buffer, batch_size)) return torch.stack(state), torch.tensor(action), torch.tensor(reward), torch.stack(next_state) ``` 3. 定义DQN算法:使用PyTorch定义DQN算法,包含训练和预测两个方法。 ```python class DQN(object): def __init__(self, state_dim, action_dim, gamma, epsilon, lr): self.qnet = QNet(state_dim, action_dim) self.target_qnet = QNet(state_dim, action_dim) self.gamma = gamma self.epsilon = epsilon self.lr = lr self.optimizer = torch.optim.Adam(self.qnet.parameters(), lr=self.lr) self.buffer = ReplayBuffer(100000) self.loss_fn = nn.MSELoss() def act(self, state): if random.random() < self.epsilon: return random.randint(0, action_dim - 1) else: with torch.no_grad(): q_values = self.qnet(state) return q_values.argmax().item() def train(self, batch_size): state, action, reward, next_state = self.buffer.sample(batch_size) q_values = self.qnet(state).gather(1, action.unsqueeze(1)).squeeze(1) target_q_values = self.target_qnet(next_state).max(1)[0].detach() expected_q_values = reward + self.gamma * target_q_values loss = self.loss_fn(q_values, expected_q_values) self.optimizer.zero_grad() loss.backward() self.optimizer.step() def update_target_qnet(self): self.target_qnet.load_state_dict(self.qnet.state_dict()) ``` 4. 训练模型:使用DQN算法进行训练,并更新目标Q网络。 ```python dqn = DQN(state_dim, action_dim, gamma=0.99, epsilon=1.0, lr=0.001) for episode in range(num_episodes): state = env.reset() total_reward = 0 for step in range(max_steps): action = dqn.act(torch.tensor(state, dtype=torch.float32)) next_state, reward, done, _ = env.step(action) dqn.buffer.push(torch.tensor(state, dtype=torch.float32), action, reward, torch.tensor(next_state, dtype=torch.float32)) state = next_state total_reward += reward if len(dqn.buffer.buffer) > batch_size: dqn.train(batch_size) if step % target_update == 0: dqn.update_target_qnet() if done: break dqn.epsilon = max(0.01, dqn.epsilon * 0.995) ``` 5. 测试模型:使用训练好的模型进行测试。 ```python total_reward = 0 state = env.reset() while True: action = dqn.act(torch.tensor(state, dtype=torch.float32)) next_state, reward, done, _ = env.step(action) state = next_state total_reward += reward if done: break print("Total reward: {}".format(total_reward)) ``` 以上就是在PyTorch中实现DQN强化学习的基本步骤。需要注意的是,DQN算法中还有很多细节和超参数需要调整,具体实现过程需要根据具体问题进行调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

韭菜盖饭

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值