用深度强化学习玩游戏之DQN实战笔记

本文介绍了使用深度强化学习DQN算法训练智能体玩《MuseDash》游戏的过程。通过图像处理提取血量和蓝量信息,设置智能体动作和奖励机制。智能体动作包括向上、向下击打,通过蓝量变化判断击打效果。在训练中,DQN结合经验回放策略更新网络。经过训练,智能体在游戏中的表现得到了提升。
摘要由CSDN通过智能技术生成

前言

本项目基于Bilibili up主蓝魔digital的项目改编,研究对象为并进行了分析,供大家学习与参考(视频链接在文末)

环境配置

Python 3.8
Tensorflow – 2.4.1
Opencv-python – 4.5.1
Cuda – 11.1
cudnn – 11.1
《MuseDash》游戏

游戏环境信息提取及建模

(1)血量信息提取

对于本文中讨论的AI智能体来说,首先需要了解自己的血量,以保证自己能够通过整个关卡。对于游戏中的血量,不便选择读取内存的方式来提取数据,故采用图像处理的方式对游戏界面的血量进行实时提取,并将其转化为数据。由于游戏界面血量接近于红色,故可以直接通过提取HSV色彩空间中的红色,判断两帧之间血条的变化,从而直接设置奖励(惩罚),如果血量低于限定值,则判断智能体死亡游戏结束。

在这里插入图片描述

(2)击打信息提取

在得知血量信息后,还需要提取智能体是否击中目标的信息,考虑到《Muse Dash》的画面信息较为复杂,不易直接提取画面中的打击提示,故决定不从连击提示和打击点进行信息提取。
在这里插入图片描述

在这里插入图片描述
由于游戏中人物在击中敌人时,蓝条会增加,且如果造成连击蓝条会有一段比较大的增量,故采用提取蓝条信息,判断蓝条两帧之间的变化的方式来判断人物的打击效果。
使用和提取血条相似的方式,选取一行像素判断蓝色的灰度区间,进行对蓝量的计数,累加得到蓝量信息,间接得到击打反馈。
在这里插入图片描述

(3)智能体动作设置

人物的动作分为向上击打、向下击打、向上长按、向下长按四种,考虑到长按操作会使计算流程存在一个空档期,在此期间智能体无法观察环境,且长按空档期时间不定,如果加入长按动作会使模型极难收敛,故不考虑长按操作。
  由于可能出现向上击打和向下击打同时出现的情况,为了使模型收敛性较好,故可将这个两个动作合成为同时击打动作。游戏中陷阱会和击打目标同时出现在上下击打点,故通过奖励设置可以避免同时击打一直产生的情况。

(4)奖励设置

在得到血量和蓝量信息后,通过动作触发奖励。
1 )对于击中的情况,蓝条增加则直接触发较小的奖励。
2 )对于连击的情况,如果判断蓝条两帧差距超过阈值则出发连击奖励。
3 )对于掉血的情况,如果血条减少则触发掉血惩罚。
4 )对于死亡的情况,如果判断死亡则触发死亡惩罚。
5 )对于蓝条收集满,触发特殊的奖励,同时蓝条清零。

所用算法——DQN(Deep Q Network)

DQN是Q学习算法与深度神经网络的结合,使用深度神经网络直接作用于RGB图像,使用target Q network来更新target,还使用了经验回放Experience replay。
算法流程:

  1. 初始化经验池   D \ D  D,其容量为   N \ N  N,用作经验回放
  2. 用随机权值初始化 动作-价值 函数网络   Q \ Q  Q 参数
  3. 用相同的权值初始化目标 动作-价值 函数网络 Q ^ \hat Q Q^ 参数
  4. 进入第一次游戏循环,游戏总共   M \ M  M
  5. 初始化事件的第一个状态   S 1 = x 1 \ S_1=x_1  S1=x1 ,预处理得到状态对应的特征输入   ϕ 1 ( S 1 ) \ \phi_1(S_1)  ϕ1(S1)
  6. 进入一次游戏循环的一步
  7. 如果概率为   ϵ \ \epsilon  ϵ 的事件发生了,选取一个随机动作   a t \ a_t  at
  8. 如果概率为   ϵ \ \epsilon  ϵ 的事件没有发生,则按贪婪策略选取此状态下最大的Q结果对应动作   a t \ a_t  at
  9. 代理执行动作   a t \ a_t  at,获得环境反馈的奖励   r t \ r_t  rt和下一时间步的游戏图像   x t + 1 \ x_{t+1}  xt+1
  10. 将此时的   a t \ a_t  at,   S t \ S_t  St,   x t + 1 \ x_{t+1}  xt+1作为下一状态   S t + 1 \ S_{t+1}  St+1,并继续处理下一时间得到游戏图像得到   ϕ t + 1 \ \phi_{t+1}  ϕt+1
  11. 将刚刚获得的状态转移   ( ϕ t , a t , r t , ϕ t + 1 ) \ (\phi_t,a_t,r_t, \phi_{t+1} )  (ϕt,at,rt,ϕt+1)存入经验池   D \ D  D
  12. 从经验池   D \ D  D中均匀随机采样一个状态转移样本数据   ( ϕ j , a j , r j , ϕ j + 1 ) \ (\phi_j,a_j,r_j, \phi_{j+1} )  (ϕj,aj,rj,ϕj+1)
  13. 计算目标值   y j \ y_j  yj,首先判断是否是一次游戏的终止状态,若是终止状态则目标值   y j = r j \ y_j=r_j  yj=rj ,如果没有终止则利用目标 Q ^ \hat Q Q^ 网络计算来得到   y j \ y_j  yj
  14. 通过   y j \ y_j  yj与实际预测网络   Q \ Q  Q 计算结果的差值,进行梯度下降算法,更新预测网络   Q \ Q  Q的参数
  15. 每隔C步用预测网络   Q \ Q  Q参数更新一次目标网络 Q ^ \hat Q Q^参数
  16. 结束该步运算
  17. 结束该次游戏循环

在训练智能体时,卷积网络的输入为将游戏图像预处理成连续 4 帧的像素的图像。预处理过程主要是将游戏图像缩放并去色,由彩色图像变为灰度图像

实际表现

游戏界面:
在这里插入图片描述

训练后成果已上传至Bilibili,视频链接:https://www.bilibili.com/video/BV1Up4y1n77y

原作者蓝魔Digital的用DQN玩只狼视频:https://www.bilibili.com/video/BV1SA411u7g9

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
强化学习玩Atari游戏是一种基于深度强化学习算法的方法,其中使用了深度Q学习算法。这种方法通过将游戏界面作为输入,直接从游戏界面中学习,以实现对Atari游戏的学习和玩耍。 具体来说,深度Q学习算法使用了经验回放和目标网络的技术。经验回放是一种存储和重复使用过去的经验的方法,它可以帮助算法更好地学习和记忆。目标网络是一个用于计算目标Q值的网络,它的参数是固定的,以减少目标Q值的变化。 在实现强化学习玩Atari游戏的过程中,可以使用深度强化学习框架,如TensorFlow或PyTorch,来构建深度Q网络。该网络将游戏界面作为输入,并输出每个动作的Q值。然后,根据Q值选择最佳动作,并执行该动作。通过不断与环境交互,更新网络参数,以优化Q值的估计。 以下是一个示例代码,演示了如何使用深度Q学习算法玩Atari游戏中的Pong: ```python import gym import numpy as np import tensorflow as tf # 创建环境 env = gym.make('Pong-v0') # 定义深度Q网络 model = tf.keras.Sequential([ tf.keras.layers.Conv2D(32, (8, 8), strides=(4, 4), activation='relu', input_shape=(84, 84, 4)), tf.keras.layers.Conv2D(64, (4, 4), strides=(2,2), activation='relu'), tf.keras.layers.Conv2D(64, (3, 3), strides=(1, 1), activation='relu'), tf.keras.layers.Flatten(), tf.keras.layers.Dense(512, activation='relu'), tf.keras.layers.Dense(env.action_space.n) ]) # 定义经验回放缓冲区 replay_buffer = [] # 定义训练参数 epsilon = 1.0 # 探索率 epsilon_decay = 0.99 # 探索率衰减率 epsilon_min = 0.01 # 最小探索率 gamma = 0.99 # 折扣因子 batch_size = 32 # 批量大小 # 定义优化器和损失函数 optimizer = tf.keras.optimizers.Adam(learning_rate=0.001) loss_fn = tf.keras.losses.MeanSquaredError() # 定义目标网络 target_model = tf.keras.models.clone_model(model) target_model.set_weights(model.get_weights()) # 定义训练函数 def train(): # 从经验回放缓冲区中随机采样一批数据 batch = np.random.choice(len(replay_buffer), size=batch_size, replace=False) states, actions, rewards, next_states, dones = zip(*[replay_buffer[i] for i in batch]) states = np.array(states) actions = np.array(actions) rewards = np.array(rewards) next_states = np.array(next_states) dones = np.array(dones) # 计算目标Q值 q_values_next = target_model.predict(next_states) targets = rewards + gamma * np.max(q_values_next, axis=1) * (1 - dones) # 计算当前Q值 with tf.GradientTape() as tape: q_values = model(states) q_values_actions = tf.reduce_sum(q_values * tf.one_hot(actions, env.action_space.n), axis=1) loss = loss_fn(targets, q_values_actions) # 更新网络参数 grads = tape.gradient(loss, model.trainable_variables) optimizer.apply_gradients(zip(grads, model.trainable_variables)) # 开始训练 for episode in range(1000): state = env.reset() state = preprocess(state) # 预处理游戏界面 done = False total_reward = 0 while not done: # 选择动作 if np.random.rand() < epsilon: action = env.action_space.sample() # 随机动作 else: q_values = model.predict(np.expand_dims(state, axis=0)) action = np.argmax(q_values) # 执行动作 next_state, reward, done, _ = env.step(action) next_state = preprocess(next_state) # 预处理游戏界面 # 存储经验 replay_buffer.append((state, action, reward, next_state, done)) # 更新状态和总奖励 state = next_state total_reward += reward # 训练网络 if len(replay_buffer) >= batch_size: train() # 更新目标网络 if episode % 10 == 0: target_model.set_weights(model.get_weights()) # 衰减探索率 epsilon = max(epsilon * epsilon_decay, epsilon_min) # 打印结果 print('Episode: {}, Total Reward: {}'.format(episode, total_reward)) # 演示游戏 state = env.reset() state = preprocess(state) done = False total_reward = 0 while not done: q_values = model.predict(np.expand_dims(state, axis=0)) action = np.argmax(q_values) next_state, reward, done, _ = env.step(action) next_state = preprocess(next_state) state = next_state total_reward += reward env.render() print('Total Reward: {}'.format(total_reward)) env.close() ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

NathanWu7

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

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

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

打赏作者

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

抵扣说明:

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

余额充值