使用强化学习快速让AI学会玩贪食蛇游戏(轻量级二十分钟训练+代码)

news/2024/5/18 23:51:18 标签: 强化学习, 算法, 游戏, 人工智能

如何让AI玩会贪食蛇,甚至比你厉害

  • 概述
  • 构建问题(强化学习求解的一般步骤)
    • 环境
    • 动作定义
    • 状态定义
    • 奖励设计
  • 训练奖励值收敛图
    • 采用第4种状态定义方法
    • 初步训练效果
    • 最终训练效果
    • 模型泛化迁移能力
  • 代码

概述

  1. 所用技术:强化学习(Deep Reinforcement Learning),属于一种无监督学习,利用奖励 r e w a r d reward reward教会智能体 A g e n t Agent Agent在合适的场景做合适的决策。
  2. 采用算法:试过两种算法D3QN和离散版本的PPO算法,最终采用离散版本PPO算法+GAE(PPO是我用过的性能最好的算法之一)
  3. 编程语言与深度学习框架:Python3.8 + torch

构建问题(强化学习求解的一般步骤)

环境

贪食蛇的环境参考了https://www.cnblogs.com/dengfaheng/p/9241267.html,在其基础上进行改动和封装,写成了符合强化学习标准的环境接口,满足如下最基本操作:

  1. .step(action),即对环境执行动作。
  2. .reset(),重置环境。
  3. .render(),渲染图像,可视化训练。

窗口设定为600*600像素,其中50*50像素格为一个单元,即整个游戏场景为12*12方格(也可以设置大,训练难度和时间会相应非线性增加)。
食物:一个单元尺寸大小。
贪食蛇:n个单元构成(n为当前贪食蛇长度)
在这里插入图片描述

动作定义

对于贪食蛇定义动作如下:
A c t i o n ∈ { 0 , 1 , 2 , 3 } Action\in \{0,1,2,3\} Action{0,1,2,3}
分别代表上下左右移动蛇头。其实更合理的是三个方向,因为蛇不能倒退,但是DRL对这个bug还是有忍耐度的。

状态定义

这个问题我试了很多种:

  1. 游戏当前帧作为RGB图像(或者二值化图像),用卷积网络提取特征,这里图像就是强化学习的state。结果发现不可行,其一是网络参数因卷积而增加,而Actor网络是需要有快速回归能力的,其二是图像必须resize,太大了训练慢,太小了特征不明显(蛇都糊了…)。
  2. 将12*12的界面当成12*12的矩阵,其中蛇头位置取2,蛇身位置取1,食物位置取-1,其余位置取0,然后把这个矩阵要么当图像用卷积,要么直接flatten为向量作为特征。结果发现效果比较差,向量维度太大,强化学习难以学习到策略。
  3. 将当前蛇头和食物的相对x坐标和y坐标作为state,实验发现效果还行,但是由于state中没有蛇的身子的信息和游戏边界的信息,蛇很容易自杀。
  4. 蛇头和食物的相对x坐标和y坐标,蛇头上、下、左、右是否有自身身体或者游戏边界作为state,效果很好,训练后AI超过普通玩家水平:
    s t a t e = [ x f o o d − x h e a d , y f o o d − y h e a d , k 1 , k 2 , k 3 , k 4 ] , k i ∈ { 0 , 1 } state=[x_{food}-x_{head},y_{food}-y_{head},k_1,k_2,k_3,k_4],k_i \in\{0,1\} state=[xfoodxhead,yfoodyhead,k1,k2,k3,k4],ki{0,1}
    其中当 k i = 1 k_i=1 ki=1时表明蛇头的第 i i i个方向上存在障碍,另外 x f o o d − x h e a d , y f o o d − y h e a d x_{food}-x_{head},y_{food}-y_{head} xfoodxhead,yfoodyhead最好归一化。

目前暂时使用第四种方案。

奖励设计

奖励是强化学习的灵魂,常起画龙点睛之作用。

  1. 初始化reward=0
  2. 如果当前state蛇吃到了食物,reward+=2
  3. 计算蛇头和食物的距离d,如果d<t,则reward += (t-d)/t(这里t取一个小正数即可比如2);
  4. 如果当前state蛇自杀,reward -= 0.5

其中第3条可以引导贪食蛇找食物,否则可能由于稀疏奖励导致训练出一个只会“苟且偷生”的蛇,但是如果你的算法性能够好,第三条可以不要

训练奖励值收敛图

采用第4种状态定义方法

家用电脑半小时内训练完毕(横轴游戏训练回合数,纵轴累计奖励回报值):
在这里插入图片描述

初步训练效果

下面这张图是初步训练的策略,其实挺像我小时候玩这个游戏时到后期的做法,但最后太长了它也没想到把自己堵死了…
在这里插入图片描述

最终训练效果

经过一系列优化,得到了一个较为满意的策略:
在这里插入图片描述
可以看到贪食蛇是会躲避自己的身体的!并且有自己的路径规划策略!

模型泛化迁移能力

在小尺寸地图上训练好的模型可直接迁移到大尺寸地图策略依旧可行:
在这里插入图片描述

代码

整个项目的所有代码和中间结果甚至是权重均已push到github,欢迎star/fork,你的星星是对我最大的帮助:
DRL4SnakeGame:一个使用强化学习快速让AI学会玩贪食蛇游戏的项目
what you need to do is to run the main.py and then run the env4Snake to test your model!
这个项目还有很多改进的点,会不时更新~


http://www.niftyadmin.cn/n/563299.html

相关文章

DEAP数据集介绍

DEAP数据介绍&#xff1a; 数据来源&#xff1a; DEAP: A Dataset for Emotion Analysis using Physiological and Audiovisual Signals (qmul.ac.uk) 数据简单介绍&#xff1a; 采集了32名&#xff08;16名男性和16名女性&#xff09;健康参与者的脑电数据。参加实验的人身…

深度学习基于DEAP的脑电情绪识别情感分类(附代码)

DEAP数据集&#xff1a; DEAP数据集来源&#xff1a; DEAP: A Dataset for Emotion Analysis using Physiological and Audiovisual Signals (qmul.ac.uk) DEAP数据集介绍&#xff1a; DEAP数据集介绍 脑电情绪识别&#xff1a; 主要分为三步骤&#xff1a;数据预处理&am…

(DEAP)基于图卷积神经网络的脑电情绪识别(附代码)

1. 数据集介绍以及特征部分见上篇文章&#xff1a; DEAP数据集介绍以及特征提取部分 深度学习基于DEAP的脑电情绪识别情感分类(附代码)_qq_3196288251的博客-CSDN博客 2. 图卷积神经网络哟结合LSTM 本文主要介绍利用图卷积神经网络结合LSTM进行脑电情绪识别。 由于脑电通道…

Pycharm导入Pyeeg安装包

pyeeg介绍及各部分功能&#xff1a; 先去看另一篇博客&#xff0c;链接如下&#xff1a; https://blog.csdn.net/qq_45874683/article/details/121384670?spm1001.2014.3001.5502 Pyeeg模块部分功能介绍 pyeeg是一个Python模块&#xff0c;具有许多用于时间序列分析的函数&…

基于深度学习的脑电情绪识别所有模型以及各部分处理安装包

先放图&#xff1a; 1.读取edf文件&#xff0c;得到脑电信号文件&#xff1a; 2.将数据处理为相应模型所需要的相应的数据形式部分&#xff1a; 3.重点来了&#xff1a;所有脑电领域会用到的模型文件&#xff01;&#xff01;&#xff01;&#xff01;&#xff1a; 4.最后运行…

(论文加源码)基于连续卷积神经网络(CNN)(SVM)(MLP)提取脑电微分熵特征的DEAP脑电情绪识别

简介&#xff1a; 主要内容是采用DEAP数据集将脑电信号进行频域分段并提取其微分熵特征&#xff0c;为了充分利用空间特征&#xff0c;结合微分熵特征将其构建为一个三维脑电特征&#xff0c;输入到连续卷积神经网络&#xff0c;并最终取得了90.24%的准确率。 提出了一种脑电特…

Pyeeg模块部分功能介绍

1.pyeeg简单介绍 PyEEG是一个Python模块&#xff08;即函数库&#xff09;&#xff0c;用于提取EEG&#xff08;脑电&#xff09;特征。正在添加更多功能。它包含构建用于特征提取的数据的函数&#xff0c;例如从给定的时间序列构建嵌入序列。它还能够将功能导出为svmlight格式…

基于deap脑电数据集的脑电情绪识别二分类算法(附代码)

想尝试一下脑电情绪识别的各个二分类算法。 代码主要分为三部分&#xff1a;快速傅里叶变换处理&#xff08;fft&#xff09;、数据预处理、以及各个模型处理。 采用的模型包括&#xff1a;决策树、SVM、KNN三个模型&#xff08;模型采用的比较简单&#xff0c;可以直接调用库…