在 Google Research Football 上利用 PPO 训练 AI (Win10)
keyanjun_AI 2024-10-15 12:31:01 阅读 83
1、前言
在笔者进行环境配置的过程中遇到了一系列的问题,其中最核心的问题在于显卡的兼容性问题,由于 Google Research Football 推荐使用的是Tensorflow 1.15版本,官方版是在 CUDA 10.0上进行编译的,笔者使用的 RTX3060 在运行训练代码时会报 “failed to run cuBLAS routine: CUBLAS_STATUS_EXECUTION_FAILED” 错误,检查显存时发现显存占用并不多,究其原因是30系显卡对 CUDA 10.0 的兼容性不好,因此本文将在 1650 Ti 显卡和 RTX3060 分别进行测试。10系和20系显卡可以参考1650 Ti 显卡的安装方法,30系和40系显卡可以参考3060显卡的安装方法。
2、1650Ti 显卡上安装强化学习环境
2.1 安装依赖
CUDA 10.0CUDNN 7.6.4python 3.7tensorflow 1.15
2.2 安装步骤
使用如下指令安装dm-sonnet和tensorflow,dm-sonnet最好安装2.*版本的,不然会与football的很多依赖项有冲突。
<code>python -m pip install dm-sonnet==2.* psutil -i https://pypi.tuna.tsinghua.edu.cn/simple
python -m pip install tensorflow-gpu==1.15 -i https://pypi.tuna.tsinghua.edu.cn/simple
使用如下指令安装OpenAI Baselines:
git clone https://github.com/openai/baselines.git
cd baselines
pip install -e . -i https://pypi.tuna.tsinghua.edu.cn/simple
使用如下指令运行训练代码,如果成功的话在终端中会出现下图所示内容:
python -m gfootball.examples.run_ppo2 --level=academy_empty_goal_close
3、3060 显卡上安装强化学习环境
在 3060 显卡上安装强化学习环境可以安装CUDA 11.7,CUDNN 8.4,这样兼容性比较好。
3.1 安装依赖
CUDA 11.7CUDNN 8.4python 3.7tensorflow 2.6
3.2 安装步骤
使用如下指令安装dm-sonnet和tensorflow,dm-sonnet最好安装2.*版本的,不然会与football的很多依赖项有冲突。
<code>python -m pip install dm-sonnet==2.* psutil -i https://pypi.tuna.tsinghua.edu.cn/simple
python -m pip install tensorflow-gpu==2.6 -i https://pypi.tuna.tsinghua.edu.cn/simple
使用如下指令安装OpenAI Baselines:
git clone https://github.com/openai/baselines.git
cd baselines
pip install -e . -i https://pypi.tuna.tsinghua.edu.cn/simple
前两步跟 1650Ti 上安装的步骤区别不大,但是对于 3060 显卡来说,安装现在才开始。如果觉得下面过程太复杂了,可以下载笔者修改好的baselines代码。首先可能会遇到 “ImportError: cannot import name ‘dtensor’ from ‘tensorflow.compat.v2.experimental’” 错误。
主要原因是tensorflow和Keras版本不匹配,Keras版本太高,应该与Tensorflow版本相同。
<code>pip install keras==2.6.0 -i https://pypi.tuna.tsinghua.edu.cn/simple
解决上面问题后,会出现“AttributeError: module ‘tensorflow’ has no attribute ‘set_random_seed’”错误:
这个错误以及后续所有类似缺少属性的错误都是因为这些属性是tensorflow 1.x版本中的变量,在tensorflow 2.x版本中都移除了,只能使用兼容模式,找到出错的文件,在文件中找到“import tensorflow as tf”语句,用“import tensorflow.compat.v1 as tf”代替“import tensorflow as tf”,这样可以解决兼容性问题,有很多文件都存在这个问题,所有类似的错误都可以用这个方法解决。
接下来还有一类问题,如下图所示,“AttributeError: ‘int’ object has no attribute ‘value’”:
这个错误也是因为tensoflow版本的问题,不过这个处理方法也比较简单,只需要在对应的语句中把".value"几个字符删除即可,所有此类问题都可以用该方法解决。
将这些问题都解决之后,就可以成功运行了。
4、使用训练的权重进行比赛
Google Research Football 支持两个模型进行对战,可以使用以下指令:
<code>python -m gfootball.play_game --players "ppo2_cnn:left_players=1,checkpoint=weights/01600;ppo2_cnn:right_players=1,checkpoint=weights/01900"
5、常见错误
在运行训练代码时可能会报:your generated code is out of date and must be regenerated with protoc >= 3.19.0
解决方法:改错误是由于 protobuf 版本太高导致的,需要降级到3.20以下
<code>pip install protobuf==3.20.* -i https://pypi.tuna.tsinghua.edu.cn/simple
在运行训练代码时可能会报:TypeError: can’t pickle FlagValues 错误。
解决方法:该错误的原因目前还不清楚,可能是依赖库的版本兼容问题,好在问题可以通过修改代码来解决。在anaconda的football环境中找到以下路径中的run_ppo2.py文件:football\lib\site-packages\gfootball\examples\run_ppo2.py 并将run_ppo2.py中的代码用如下代码替换:
<code>"""Runs football_env on OpenAI's ppo2."""
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import multiprocessing
import os
from absl import app
from absl import flags
from baselines import logger
from baselines.bench import monitor
from baselines.common.vec_env.subproc_vec_env import SubprocVecEnv
from baselines.ppo2 import ppo2
import gfootball.env as football_env
from gfootball.examples import models
FLAGS = flags.FLAGS
flags.DEFINE_string('level', 'academy_empty_goal_close',
'Defines type of problem being solved')
flags.DEFINE_enum('state', 'extracted_stacked', ['extracted',
'extracted_stacked'],
'Observation to be used for training.')
flags.DEFINE_enum('reward_experiment', 'scoring',
['scoring', 'scoring,checkpoints'],
'Reward to be used for training.')
flags.DEFINE_enum('policy', 'cnn', ['cnn', 'lstm', 'mlp', 'impala_cnn',
'gfootball_impala_cnn'],
'Policy architecture')
flags.DEFINE_integer('num_timesteps', int(2e6),
'Number of timesteps to run for.')
flags.DEFINE_integer('num_envs', 1,
'Number of environments to run in parallel.')
flags.DEFINE_integer('nsteps', 128, 'Number of environment steps per epoch; '
'batch size is nsteps * nenv')
flags.DEFINE_integer('noptepochs', 4, 'Number of updates per epoch.')
flags.DEFINE_integer('nminibatches', 8,
'Number of minibatches to split one epoch to.')
flags.DEFINE_integer('save_interval', 100,
'How frequently checkpoints are saved.')
flags.DEFINE_integer('seed', 0, 'Random seed.')
flags.DEFINE_float('lr', 0.00008, 'Learning rate')
flags.DEFINE_float('ent_coef', 0.01, 'Entropy coeficient')
flags.DEFINE_float('gamma', 0.993, 'Discount factor')
flags.DEFINE_float('cliprange', 0.27, 'Clip range')
flags.DEFINE_float('max_grad_norm', 0.5, 'Max gradient norm (clipping)')
flags.DEFINE_bool('render', False, 'If True, environment rendering is enabled.')
flags.DEFINE_bool('dump_full_episodes', False,
'If True, trace is dumped after every episode.')
flags.DEFINE_bool('dump_scores', False,
'If True, sampled traces after scoring are dumped.')
flags.DEFINE_string('load_path', None, 'Path to load initial checkpoint from.')
def create_single_football_env(iprocess, level, state, reward_experiment, render,
dump_full_episodes, dump_scores):
env = football_env.create_environment(
env_name=level,
stacked=('stacked' in state),
rewards=reward_experiment,
logdir=logger.get_dir(),
write_goal_dumps=dump_scores and (iprocess == 0),
write_full_episode_dumps=dump_full_episodes and (iprocess == 0),
render=render and (iprocess == 0),
dump_frequency=50 if render and iprocess == 0 else 0)
env = monitor.Monitor(env, logger.get_dir() and os.path.join(logger.get_dir(), str(iprocess)))
return env
def train(level, state, reward_experiment, policy, num_timesteps, num_envs, nsteps, noptepochs,
nminibatches, save_interval, seed, lr, ent_coef, gamma, cliprange, max_grad_norm,
render, dump_full_episodes, dump_scores, load_path):
vec_env = SubprocVecEnv([
(lambda _i=i: create_single_football_env(_i, level, state, reward_experiment, render,
dump_full_episodes, dump_scores))
for i in range(num_envs)
], context=None)
# Import tensorflow after we create environments. TF is not fork sake, and
# we could be using TF as part of environment if one of the players is
# controlled by an already trained model.
import tensorflow.compat.v1 as tf
ncpu = multiprocessing.cpu_count()
config = tf.ConfigProto(allow_soft_placement=True,
intra_op_parallelism_threads=ncpu,
inter_op_parallelism_threads=ncpu)
config.gpu_options.allow_growth = True
tf.Session(config=config).__enter__()
ppo2.learn(network=policy,
total_timesteps=num_timesteps,
env=vec_env,
seed=seed,
nsteps=nsteps,
nminibatches=nminibatches,
noptepochs=noptepochs,
max_grad_norm=max_grad_norm,
gamma=gamma,
ent_coef=ent_coef,
lr=lr,
log_interval=1,
save_interval=save_interval,
cliprange=cliprange,
load_path=load_path)
if __name__ == '__main__':
# app.run(train)
app.run(lambda _: train(
FLAGS.level,
FLAGS.state,
FLAGS.reward_experiment,
FLAGS.policy,
FLAGS.num_timesteps,
FLAGS.num_envs,
FLAGS.nsteps,
FLAGS.noptepochs,
FLAGS.nminibatches,
FLAGS.save_interval,
FLAGS.seed,
FLAGS.lr,
FLAGS.ent_coef,
FLAGS.gamma,
FLAGS.cliprange,
FLAGS.max_grad_norm,
FLAGS.render,
FLAGS.dump_full_episodes,
FLAGS.dump_scores,
FLAGS.load_path
))
在windows系统上若在训练时打开了渲染的选项,可能会报“BrokenPipeError: [WinError 109] 管道已结束。”或者“OSError: [WinError 6] 句柄无效。”的错误,所以不建议在训练时开启渲染。
声明
本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。