一文实践强化学习训练游戏ai--doom枪战游戏实践

一文实践强化学习训练游戏ai–doom枪战游戏实践
上次文章写道下载doom的环境并尝试了简单的操作,这次让我们来进行对象化和训练、验证,如果你有基础,可以直接阅读本文,不然请你先阅读Doom基础知识,其中包含了下载、动作等等的基础知识。
本次与之前的马里奥训练不同,马里奥是已经有做好的step等函数的,而这个doom没有,但也因此我们可以更好的一窥训练的过程。
完整代码在最后,可以复制执行。

文章目录

  • 一、训练模型
    • 1、vizdoom_train类
      • 1)__init__
      • 2)step
      • 3)togray
      • 4)其他函数
    • 2、保存模型函数
    • 3、训练模型
  • 二、成果验收
  • 完整代码
    • 训练代码
    • 测试代码

一、训练模型

1、vizdoom_train类

这是我们的训练基类,由于我们想用openai gym环境,因此我们需要手写此环境必须的__init__、step等函数

1)init

在这个函数中,我们要定义训练的观察空间(即游戏图像)、动作空间(即ai可以执行的操作)和一些基础设置。

        VizDoom_basic_cfg = r"C:/Users/tttiger/Desktop/ViZDoom-master/ViZDoom-master/scenarios/basic.cfg"self.game = vizdoom.DoomGame()self.game.load_config(VizDoom_basic_cfg)if render == False: self.game.set_window_visible(False)else:self.game.set_window_visible(True)self.game.init()

此处,我们先指定游戏文件的位置,然后加一个判断,决定是否允许游戏窗口显示出来,最后初始化游戏。
初始化后,我们就要规定观察空间和动作空间了

        self.observation_space = Box(low=0, high=255, shape=(100,160,1), dtype=np.uint8) self.action_space = Discrete(3)

观察空间是我们游戏的界面,这是一个灰化后的图像,所以维度为1,大小为100*160
动作空间为离散空间3,即可以选取动作0、1、2,我们只需要在后续的代码中指定数字指代的动作就可以了。

2)step

step函数非常关键,这是ai执行动作的时候会调用的函数。
首先,我们定义我们的动作

        actions = np.identity(3,dtype=np.uint8)reward = self.game.make_action(actions[action], 4) 

这部分的详细解释在Doom基础知识中,事实上就是定义一个矩阵,调用游戏文件中的左移、右移和射击。
接下来,我们要获取当前的状态,比如得分,游戏图像等,这样我们才可以训练。

        try:state = self.game.get_state()img = state.screen_bufferimg = self.togray(img)info = state.game_variables[0]except:img = np.zeros(self.observation_space.shape)info = 0 finally:info = {"info":info}done = self.game.is_episode_finished()#img_show(img)return img,reward,done,info

使用try,是因为gameover时有些内容获取不到,为了防止程序因此暂停,用try。最后,我们要把info变成字典形式,这是因为openai gym环境时这么要求的。为了方便理解,这里可以调用imgshow,查看目前的图像,其实现如下。

def img_show(img):plt.imshow(img)plt.show()time.sleep(5)

3)togray

灰度化图像,我们知道,彩色图像时由rgb三个颜色矩阵组成,但这么大的数据量给我们的训练增添的很多负担,于是我们采用灰度图。同时,我们缩小图像,这样可以训练的更快。

    def togray(self,observation):gray = cv2.cvtColor(np.moveaxis(observation, 0, -1), cv2.COLOR_BGR2GRAY)resize = cv2.resize(gray, (160,100), interpolation=cv2.INTER_CUBIC)state = np.reshape(resize, (100,160,1))return state

observation 是一个 NumPy 数组,通常表示图像数据。
np.moveaxis 是 NumPy 库中的一个函数,用于重新排列数组的轴。
参数 0 表示将第0轴(通常是颜色通道)移动到新位置的最后一个轴位置(即 -1)。
例如,如果 observation 的形状是 (C, H, W)(即颜色通道在第一个维度),经过 np.moveaxis 后,形状将变为 (H, W, C),这对于 OpenCV 处理图像更为常见,因为 OpenCV 期望颜色通道是图像的最后一个维度。

cv2.cvtColor 是 OpenCV 中用于颜色空间转换的函数。
第一个参数是输入图像(在这里是经过 np.moveaxis 处理后的图像)。
第二个参数 cv2.COLOR_BGR2GRAY 指定了将图像从 BGR 颜色空间转换为灰度图像。

4)其他函数

我们要定义一个关闭游戏的函数close

   def close(self):self.game.close()

以及一个reset函数,用于在结束一个游戏后,重置状态,继续下一轮训练

    def reset(self):state = self.game.new_episode()state = self.game.get_state()return self.togray(state.screen_buffer)

至此,我们已经成功地把这个独立游戏包装成了可以使用openai gym的环境的游戏。

2、保存模型函数

class TrainAndLoggingCallback(BaseCallback):def __init__(self, check_freq, save_path, verbose=1):super(TrainAndLoggingCallback, self).__init__(verbose)self.check_freq = check_freqself.save_path = save_pathdef _init_callback(self):if self.save_path is not None:os.makedirs(self.save_path, exist_ok=True)def _on_step(self):if self.n_calls % self.check_freq == 0:model_path = os.path.join(self.save_path, 'best_model_{}'.format(self.n_calls))self.model.save(model_path)return True

我们使用这段代码来存档数据,这部分复制即可

3、训练模型

首先,我们指定训练结果保存的路径

    CHECKPOINT_DIR = './train/train_basic'LOG_DIR = './logs/log_basic'callback = TrainAndLoggingCallback(check_freq=10000, save_path=CHECKPOINT_DIR)    ```

然后我们调用训练函数进行训练

    env = vizdoom_train(render=False)model = PPO('CnnPolicy', env, tensorboard_log=LOG_DIR, verbose=1, learning_rate=0.0001, n_steps=2048)model.learn(total_timesteps=100000, callback=callback)

这里我们使用PPO这个强化学习算法。

经过几十分钟的等待,就得到训练好的模型了

二、成果验收

训练好模型后,我们要使用模型,看看效果。
首先,我们载入训练好的模型

model = PPO.load('./train/train_basic/best_model_100000')

然后测试以下模型的平均得分

mean_reward, _ = evaluate_policy(model, env, n_eval_episodes=5)

这样还不够直观,我们让ai玩给我们看


for episode in range(100): obs = env.reset()done = Falsetotal_reward = 0while not done: action, _ = model.predict(obs)obs, reward, done, info = env.step(action)time.sleep(0.20)total_reward += rewardprint('Total Reward for episode {} is {}'.format(total_reward, episode))time.sleep(2)

我们首先让ai模型预测,然后将预测的动作输入step函数,然后展示页面。

如图所示,平均得分非常高,基本能快速索敌,然后一枪秒杀。
至此,我们完成了ai的训练。

完整代码

训练代码

from gym import Env
from gym.spaces import Discrete,Box
import cv2
from vizdoom import *
import vizdoom
import random
import time
import numpy as np
#DIS离散空间 作用类似于random
#box用来装游戏图像
from matplotlib import pyplot as plt
class vizdoom_train(Env):def __init__(self, render=True):super().__init__()VizDoom_basic_cfg = r"C:/Users/tttiger/Desktop/ViZDoom-master/ViZDoom-master/scenarios/basic.cfg"self.game = vizdoom.DoomGame()self.game.load_config(VizDoom_basic_cfg)if render == False: self.game.set_window_visible(False)else:self.game.set_window_visible(True)self.game.init()self.observation_space = Box(low=0, high=255, shape=(100,160,1), dtype=np.uint8) self.action_space = Discrete(3)def step(self,action):actions = np.identity(3,dtype=np.uint8)reward = self.game.make_action(actions[action], 4) try:state = self.game.get_state()img = state.screen_bufferimg = self.togray(img)info = state.game_variables[0]except:img = np.zeros(self.observation_space.shape)info = 0 finally:info = {"info":info}done = self.game.is_episode_finished()#img_show(img)return img,reward,done,infodef close(self):self.game.close()def reset(self):state = self.game.new_episode()state = self.game.get_state()return self.togray(state.screen_buffer)def togray(self,observation):gray = cv2.cvtColor(np.moveaxis(observation, 0, -1), cv2.COLOR_BGR2GRAY)resize = cv2.resize(gray, (160,100), interpolation=cv2.INTER_CUBIC)state = np.reshape(resize, (100,160,1))return statedef img_show(img):plt.imshow(img)plt.show()time.sleep(5)# Import os for file nav
import os 
# Import callback class from sb3
from stable_baselines3.common.callbacks import BaseCallback
class TrainAndLoggingCallback(BaseCallback):def __init__(self, check_freq, save_path, verbose=1):super(TrainAndLoggingCallback, self).__init__(verbose)self.check_freq = check_freqself.save_path = save_pathdef _init_callback(self):if self.save_path is not None:os.makedirs(self.save_path, exist_ok=True)def _on_step(self):if self.n_calls % self.check_freq == 0:model_path = os.path.join(self.save_path, 'best_model_{}'.format(self.n_calls))self.model.save(model_path)return Trueif __name__ == "__main__":CHECKPOINT_DIR = './train/train_basic'LOG_DIR = './logs/log_basic'callback = TrainAndLoggingCallback(check_freq=10000, save_path=CHECKPOINT_DIR)    train = vizdoom_train()from stable_baselines3 import PPOenv = vizdoom_train(render=False)model = PPO('CnnPolicy', env, tensorboard_log=LOG_DIR, verbose=1, learning_rate=0.0001, n_steps=2048)model.learn(total_timesteps=100000, callback=callback)

测试代码

from stable_baselines3.common.evaluation import evaluate_policy
from stable_baselines3 import PPO
import time
model = PPO.load('./train/train_basic/best_model_100000')from second_gym import vizdoom_train
env = vizdoom_train(render=True)mean_reward, _ ,_= evaluate_policy(model, env, n_eval_episodes=5)print(mean_reward)for episode in range(100): obs = env.reset()done = Falsetotal_reward = 0while not done: action, _ = model.predict(obs)obs, reward, done, info = env.step(action)time.sleep(0.20)total_reward += rewardprint('Total Reward for episode {} is {}'.format(total_reward, episode))time.sleep(2)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/3223824.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

需求分析|泳道图 ProcessOn教学

文章目录 1.为什么使用泳道图2.具体例子一、如何绘制确定好泳道中枢的角色在中央基于事实来绘制过程不要纠结美观先画主干处理流程再画分支处理流程一个图表达不完,切分子流程过程数不超25 ,A4纸的幅面处理过程过程用动词短语最后美化并加上序号酌情加上…

vb.netcad二开自学笔记8:界面之任务窗格

使用net可以创建一个类似属性面板的自定义的任务窗格,从而实现应用程序更丰富的人机交互。 1、添加一个自定义控件 2、在前面创建的代码框架内增加一个命令函数ShowMyPalette Imports System.Windows.Media.Imaging Imports Autodesk.AutoCAD.ApplicationServices …

解码技术债:AI代码助手与智能体的革新之道

技术债 技术债可能来源于多种原因,比如时间压力、资源限制、技术选型不当等。它可以表现为代码中的临时性修补、未能彻底解决的设计问题、缺乏文档或测试覆盖等。虽然技术债可以帮助快速推进项目进度,但长期来看,它会增加软件维护的成本和风险…

PID控制与模糊PID控制的比较

一、PID控制器的设计 1.PID控制原理图: PID控制其结构框图如下图所示: 图1:PID控制器结构框图 2.PID控制器传递函数的一般表达式 PID控制器传递函数的一般表达形式为: 其中kp为比例增益;ki为积分增益;k…

html H5 dialog弹窗学习,实现弹窗显示内容 替代confirm、alert

html H5 dialog弹窗学习,实现弹窗内容 替代confirm 框架使用的mui,使用mui.confirm() 弹窗内容过多时,弹窗被撑的到屏幕外去了,使用H5 dialog 标签自定义一个固定大小的弹窗,内容过多时可下拉显示 效果展示 隐私政策内容很多,可以下拉显示 代码 myDialog.css dialog{p…

2024年信息系统项目管理师1批次上午客观题参考答案及解析(3)

51、探索各种选项,权衡包括时间与成本、质量与成本、风险与进度、进度与质量等多种因素,在整个过程中,舍弃无效或次优的替代方案,这种不确定性应对方法是()。 A.集合设计 B.坚韧性 C.多种结果…

odoo17 常见升级问题

通用问题 模型名变更 字段变更 方法名变更 方法参数变更 xml数据结构定义变化 xml的id变更 view视图变化,导致xpath路径出差 template结构变化,,导致xpath路径出差,或者id不存在 升16问题 前端owl的架构变化 升17问题 前端 标…

db期末复习自用[应试向 附习题]

第一章 数据库系统实现整体数据的结构化,主要特征之一,是db区别于文件系统的本质区别。 数据库系统三个阶段:人工、文件、数据库系统。 数据库管理系统的功能:数据库定义、操纵 、(保护、存储、维护)、数…

招投标信息采集系统:让您的企业始终站在行业前沿

一、为何招投标信息如此关键? 在经济全球化的大背景下,招投标活动日益频繁,成为企业获取项目、拓展市场的主流方式之一。招投标信息采集,作为企业战略决策的前置环节,其重要性不言而喻。它不仅关乎企业能否第一时间发…

Open3D 点对面的ICP算法配准(精配准)

目录 一、概述 1.1核心思想 1.2实现步骤 二、代码实现 2.1关键函数 2.2完整代码 三、实现效果 3.1原始点云 3.2配准后点云 3.3计算数据 一、概述 基于点对面的ICP(Iterative Closest Point)配准算法是ICP的一种变体,它通过最小化源…

昇思MindSpore学习总结十二 —— ShuffleNet图像分类

当前案例不支持在GPU设备上静态图模式运行,其他模式运行皆支持。 1、ShuffleNet网络介绍 ShuffleNetV1是旷视科技提出的一种计算高效的CNN模型,和MobileNet, SqueezeNet等一样主要应用在移动端,所以模型的设计目标就是利用有限的计算资源来达…

数学建模中常用的数据处理方法

常用的数据处理方法 本文参考 B站西电数模协会的讲解视频 ,只作笔记提纲,想要详细学习具体内容请观看 up 的学习视频。一般来说国赛的 C 题一般数据量比较大。 这里介绍以下两种方法: 数据预处理方法 数据分析方法 数据预处理方法 1. 数据…

【电脑应用技巧】如何寻找电脑应用的安装包华为电脑、平板和手机资源交换

电脑的初学者可能会直接用【百度】搜索电脑应用程序的安装包,但是这样找到的电脑应用程序安装包经常会被加入木马或者强制捆绑一些不需要的应用装入电脑。 今天告诉大家一个得到干净电脑应用程序安装包的方法,就是用【联想的应用商店】。联想电脑我是一点…

alibabacloud学习笔记11

讲解什么是配置中心及使用前后的好处 讲解Nacos作为配置中心面板介绍 官方文档 Nacos config alibaba/spring-cloud-alibaba Wiki GitHub 加入依赖: 订单服务和视频服务也加上这个依赖。 讲解Nacos作为配置中心实战 订单服务添加配置。 我们注释掉之前的配置。 …

现代化3D Web轻量引擎HOOPS Communicator:基于ESM的代码库转型!

HOOPS Communicator自2024.2.0版本起,向基于ECMAScript Modules (ESM)的系统迁移的决策和技术细节。文章分析了这一转型对代码组织、封装、依赖管理、性能以及与现代JavaScript开发实践兼容性的积极影响,并讨论了IIFE和UMD的兼容性支持。 引言 随着Jav…

Dynamics365 UCI下的高级查找(不要留恋Classic了)

UCI界面已经用了多年了,在Classic下的的高级查找按钮(漏斗icon)已不见踪影 但因为使用习惯问题,还是有人会通过右上角高级设置,进入Classic界面找到漏斗Icon来使用高级查找 但新的UCI风格下已经没了高级查找的概念,取而代之的是基…

C++代码编程学习:基于对象的编程风格——习题4.5(Essential C++ 第四章)

C中基于对象的编程风格的学习,非常有难度,概念很抽象,操作起来也比较费脑子,这里主要把一些知识点和习题给过一遍! 一、前言 C中基于对象的编程风格的学习(Essential C 第四章)。 二、例题 -…

设计无缝体验:交互设计流程全解析

完整的产品交互设计流程是什么?完整的产品交互设计流程包括研究用户需求、指定信息架构、制作产品原型、进行用户测试和实时发布产品。交互设计就是从人与产品之间的关系入手,通过产品设计来满足大众的日常需求。随着网络技术的流行,产品交互…

快速将一个网址打包成一个exe可执行文件

一、电脑需要node环境 如果没有下面有安装教程: node.js安装及环境配置超详细教程【Windows系统安装包方式】 https://blog.csdn.net/weixin_44893902/article/details/121788104 我的版本是v16.13.1 二、安装nativefier 这是一个GitHub上的开源项目&#xff1a…

Codeforces Round 954 (Div. 3) F. Non-academic Problem

思路&#xff1a;考虑缩点&#xff0c;因为是无向图&#xff0c;所以双连通分量缩完点后是一棵树&#xff0c;我们去枚举删除每一条树边的答案&#xff0c;然后取最小值即可。 #include <bits/stdc.h>using namespace std; const int N 3e5 5; typedef long long ll; …