深度强化学习DQN训练避障

目录

一.前言

二.代码

2.1完整代码

2.2运行环境

2.3动作空间

2.4奖励函数

2.5状态输入

2.6实验结果


一.前言

深度Q网络(DQN)是深度强化学习领域的一项革命性技术,它成功地将深度学习的强大感知能力与强化学习的决策能力相结合。在过去的几年里,DQN已经在许多复杂的问题上展示了其卓越的性能,从经典的Atari游戏到更复杂的机器人控制任务。特别值得一提的是,DQN在处理高维状态空间和动作空间的问题时表现出了显著的优势,使得它能够处理传统强化学习方法难以解决的难题。

二维环境避障问题是强化学习领域的一个经典问题,它要求智能体在二维空间中移动,同时避免与障碍物碰撞。这个问题看似简单,但实际上涉及到了许多复杂的因素,如环境的不确定性、部分可观察性、以及智能体的感知和决策能力限制等。因此,开发一种能够有效解决二维环境避障问题的方法具有重要的实际意义和应用价值。

近年来,随着深度学习和强化学习技术的不断发展,基于DQN的二维环境避障方法已经取得了显著的进展。通过利用深度学习的强大特征提取能力,DQN能够从原始的环境状态中学习到有用的特征表示,并基于这些特征进行高效的决策。此外,DQN还引入了经验回放和目标网络等关键技术,进一步提高了算法的稳定性和收敛速度。

本文研究如何让智能体在一个二维障碍物环境中进行避障。

二.代码

2.1完整代码

import gym  
import torch,copy
import torch.nn as nn
import torch.nn.functional as F
import numpy as np  
from gym import spaces  
from gym.utils import seeding  
import matplotlib.pyplot as plt  
#超参数
BATCH_SIZE = 32
LR = 0.01
EPSILON = 0.9 #随机选取的概率,如果概率小于这个随机数,就采取greedy的行为
GAMMA = 0.9
TARGET_REPLACE_ITER = 100
MEMORY_CAPACITY = 2000
N_ACTIONS=len(np.arange(0, 2*np.pi, 0.1))
N_STATES=4
ENV_A_SHAPE =0
class Net(nn.Module):def __init__(self, ):super(Net, self).__init__()self.fc1 = nn.Linear(N_STATES, 500)self.fc1.weight.data.normal_(0, 0.1)   # initializationself.out = nn.Linear(500, N_ACTIONS)self.out.weight.data.normal_(0, 0.1)   # initializationdef forward(self, x):x = self.fc1(x)x = F.relu(x)actions_value = self.out(x)return actions_value
class DQN(object):def __init__(self):#DQN是Q-Leaarning的一种方法,但是有两个神经网络,一个是eval_net一个是target_net#两个神经网络相同,参数不同,是不是把eval_net的参数转化成target_net的参数,产生延迟的效果self.eval_net=Net()self.target_net =copy.deepcopy(self.eval_net)self.learn_step_counter = 0 #学习步数计数器self.memory_counter = 0 #记忆库中位值的计数器self.memory = np.zeros((MEMORY_CAPACITY,N_STATES * 2 + 2)) #初始化记忆库#记忆库初始化为全0,存储两个state的数值加上一个a(action)和一个r(reward)的数值self.optimizer = torch.optim.Adam(self.eval_net.parameters(),lr = LR)self.loss_func = nn.MSELoss() #优化器和损失函数    #接收环境中的观测值,并采取动作def choose_action(self,x):global EPSILON#x为观测值x = torch.unsqueeze(torch.FloatTensor(x),0)if np.random.uniform() < EPSILON:#随机值得到的数有百分之九十的可能性<0.9,所以该if成立的几率是90%#90%的情况下采取actions_value高的作为最终动作actions_value = self.eval_net.forward(x)action = torch.max(actions_value,1)[1].data.numpy()action = action[0] if ENV_A_SHAPE == 0 else action.reshape(ENV_A_SHAPE) # return the argmax indexelse:#其他10%采取随机选取动作action = np.random.randint(0,N_ACTIONS) #从动作中选一个动作action = action if ENV_A_SHAPE == 0 else action.reshape(ENV_A_SHAPE)return action    #记忆库,存储之前的记忆,学习之前的记忆库里的东西def store_transition(self,s,a,r,s_):transition = np.hstack((s, [a, r], s_))# 如果记忆库满了, 就覆盖老数据index = self.memory_counter % MEMORY_CAPACITYself.memory[index, :] = transitionself.memory_counter += 1def learn(self):# target net 参数更新,每隔TARGET_REPLACE_ITE更新一下if self.learn_step_counter % TARGET_REPLACE_ITER == 0:self.target_net.load_state_dict(self.eval_net.state_dict())self.learn_step_counter += 1#targetnet是时不时更新一下,evalnet是每一步都更新# 抽取记忆库中的批数据sample_index = np.random.choice(MEMORY_CAPACITY, BATCH_SIZE)b_memory = self.memory[sample_index, :] #打包记忆,分开保存进b_s,b_a,b_r,b_sb_s = torch.FloatTensor(b_memory[:, :N_STATES])b_a = torch.LongTensor(b_memory[:, N_STATES:N_STATES+1].astype(int))b_r = torch.FloatTensor(b_memory[:, N_STATES+1:N_STATES+2])b_s_ = torch.FloatTensor(b_memory[:, -N_STATES:])# 针对做过的动作b_a, 来选 q_eval 的值, (q_eval 原本有所有动作的值)q_eval = self.eval_net(b_s).gather(1, b_a)  # shape (batch, 1)q_next = self.target_net(b_s_).detach()     # q_next 不进行反向传递误差, 所以 detachq_target = b_r + GAMMA * q_next.max(1)[0]   # shape (batch, 1)loss = self.loss_func(q_eval, q_target)# 计算, 更新 eval netself.optimizer.zero_grad()loss.backward() #误差反向传播self.optimizer.step()class RobotEnv(gym.Env):  metadata = {'render.modes': ['human']}  def __init__(self):  super(RobotEnv, self).__init__()  self.grid_size = 1000  self.viewobs = np.zeros((self.grid_size, self.grid_size))  self.robot_radius = 10  self.obstacle_radius = 50  self.robot_pos = np.array([self.grid_size // 8, self.grid_size // 2])  self.obstacle_pos = np.array([self.grid_size *3// 4, self.grid_size // 2])  self.target_pos = np.array([self.grid_size *7 // 8, self.grid_size // 2])  self.action_space =np.arange(0, 2*np.pi, 0.1)  self.observation_space = spaces.Box(low=0, high=1, shape=(self.grid_size, self.grid_size))  self._seed()  def _reset(self):self.robot_pos = np.array([self.grid_size  // 8, self.grid_size // 2])  self.obstacle_pos = np.array([self.grid_size *3// 4, self.grid_size // 2])  self.observation_space = spaces.Box(low=0, high=1, shape=(self.grid_size, self.grid_size))  return self._get_obs()def _seed(self, seed=None):  self.np_random, seed = seeding.np_random(seed)  return [seed]  def _step(self, action):  angle = action*0.1  dx = self.robot_radius * np.cos(angle)  dy = self.robot_radius * np.sin(angle)  new_pos = self.robot_pos + np.array([dx, dy])  if np.linalg.norm(new_pos - self.obstacle_pos) <= self.obstacle_radius:  reward = -1done = True  elif self.robot_pos[0]<=self.robot_radius+self.robot_radius or self.robot_pos[0]>=self.grid_size-self.robot_radius-self.robot_radius:reward=-1done = True  elif self.robot_pos[1]<=self.robot_radius+self.robot_radius or self.robot_pos[1]>=self.grid_size-self.robot_radius-self.robot_radius:reward=-1done = True  else:  reward = 1 / (1 + np.linalg.norm(new_pos - self.target_pos))  done = False  self.robot_pos = new_pos  return self._get_obs(), reward, done, {}  def _get_obs(self):  self.viewobs = np.zeros((self.grid_size, self.grid_size))  self.viewobs[int(self.robot_pos[0])][int(self.robot_pos[1])] = 1.0self.viewobs[int(self.obstacle_pos[0] - self.obstacle_radius):int(self.obstacle_pos[0] + self.obstacle_radius),   int(self.obstacle_pos[1] - self.obstacle_radius):int(self.obstacle_pos[1] + self.obstacle_radius)] = 0.5  obs=[self.robot_pos[0],self.robot_pos[1],self.obstacle_pos[0],self.obstacle_pos[1]]return obsdef _render(self, mode='human', close=False):  if close:  return  plt.imshow(self.viewobs, cmap='gray')  plt.scatter(self.robot_pos[1], self.robot_pos[0], c='red')  plt.scatter(self.obstacle_pos[1], self.obstacle_pos[0], c='blue')  plt.xlim([0, self.grid_size])  plt.ylim([0, self.grid_size])  #plt.show()  plt.pause(0.01)  plt.clf()  if __name__ == "__main__":  env = RobotEnv()  dqn = DQN()#for i in range(400000):i=0while True:s=env.reset()for j in range(300):  # Run for 100 steps as an example  action  = dqn.choose_action(s) s_, reward, done, info = env.step(action)  print(i)if i>=200000:env.render()  dqn.store_transition(s,action,reward,s_)if dqn.memory_counter > MEMORY_CAPACITY:dqn.learn()if done:  print("Episode finished after {} timesteps".format(i+1))  breaks = s_ # 现在的状态赋值到下一个状态上去i=i+1

2.2运行环境

gym== 0.7.0

torch==2.1.1

2.3动作空间

    在深度强化学习领域中,动作空间的设计对于智能体的决策能力和学习效果具有至关重要的影响。针对连续动作空间的问题,一种常见的处理方式是将其离散化,以便应用离散动作空间的强化学习算法。本实验提出了一种将0-2π的连续动作空间等分为63个离散动作的方法。

    通过采用等分为63个离散动作的策略。使得实验在保留了足够的动作分辨率的同时,避免了过度离散化可能带来的维度灾难问题。通过将动作空间划分为足够细密的离散区间,智能体能够更精确地控制自身的行为,从而在面对复杂环境时实现更好的性能。

2.4奖励函数

在本研究中,我们设计的奖励函数主要基于两个核心原则:

  1. 靠近障碍物的奖励:当智能体靠近障碍物后方时,将获得一个与距离大小成反比的奖励值。具体而言,随着智能体逐渐接近障碍物,奖励值将逐渐增大,以鼓励智能体保持与障碍物的安全距离。这种设计策略旨在通过提供即时的正反馈来促使智能体学习避免与障碍物发生碰撞的行为。
  2. 违反仿真边界或进入障碍物区域的惩罚:一旦智能体离开仿真边界或进入障碍物区域,将获得一个负奖励(惩罚),并且仿真将立即停止。这种严厉的惩罚机制确保了智能体能够清晰地认识到这些行为的不可取性,从而在学习过程中避免重复犯下相同的错误。

2.5状态输入

    在本研究中,我们将智能体的当前位置以及障碍物的位置信息作为状态输入。具体来说,状态空间包括智能体的二维坐标和障碍物的二维坐标。这样的设计使得智能体能够直接感知到周围环境的信息,并根据这些信息做出相应的决策。

2.6实验结果

    无论是在静态还是动态环境中,智能体都能够准确地感知到障碍物的存在,并有效地规划出避开障碍物的路径。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Kafka集群详解

Kafka介绍Kafka集群介绍Kafka集群特点Kafka集群搭建在这里插入图片描述Kafka集群如何进行故障切换Kafka集群Leader的选举Kafka集群如何快速横向拓展Kafka集群搭建最佳实践Kafka集群可以使用单节点Zookeeper吗Kafka集群的消费者信息保存在那里Kafka集群的Topic的分区数的设置规则…

YOLOv8改进 添加可变形注意力机制DAttention

一、Deformable Attention Transformer论文 论文地址&#xff1a;arxiv.org/pdf/2201.00520.pdf 二、Deformable Attention Transformer注意力结构 Deformable Attention Transformer包含可变形注意力机制&#xff0c;允许模型根据输入的内容动态调整注意力权重。在传统的Tra…

鸿蒙 Window 环境的搭建

鸿蒙操作系统是国内自研的新一代的智能终端操作系统&#xff0c;支持多种终端设备部署&#xff0c;能够适配不同类别的硬件资源和功能需求。是一款面向万物互联的全场景分布式操作系统。 下载、安装与配置 DevEco Studio支持Windows系统和macOS系统 Windows系统配置华为官方推…

小程序面试题 | 17.精选小程序面试题

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Nmap使用

Nmap 文章目录 Nmap端口扫描及其原理端口扫描用法Zenmap配置说明 Nmap 是一款开源免费的网络发现&#xff08;Network Discovery&#xff09;和安全审计&#xff08;Security Auditing&#xff09;工具官网为&#xff1a;www.nmap.org。 一般情况下&#xff0c;Nmap用于列举网…

从0开始界面设计师 Qt Designer

QT程序界面的 一个个窗口、控件&#xff0c;就是像上面那样用相应的代码创建出来的。 但是&#xff0c;把你的脑海里的界面&#xff0c;用代码直接写出来&#xff0c;是有些困难的。 很多时候&#xff0c;运行时呈现的样子&#xff0c;不是我们要的。我们经常还要修改代码调整界…

day12--java高级编程:网络通讯

5 Day19–网络通信(Socket通信) 说明&#xff1a; io流是跟本地的文件进行数据的传输&#xff0c;读或者写。网络通信&#xff1a;数据在网络中进行的传输。 本章专题与脉络 1. 网络编程概述 Java是 Internet 上的语言&#xff0c;它从语言级上提供了对网络应用程序的支持&…

Maven项目提示Ignored pom.xml问题

1 环境 &#xff08;1&#xff09;IDEA开发工具&#xff1a;2022.2.1 &#xff08;2&#xff09;JDK&#xff1a;Java17&#xff08;Spring6要求JDK最低版本是Java17&#xff09; &#xff08;3&#xff09;Spring&#xff1a;6.1.2 &#xff08;4&#xff09;Maven 3.8.8 2 …

react+redux+antd-mobile 之 记账本案例

1.环境搭建 //使用CRA创建项目&#xff0c;并安装必要依赖&#xff0c;包括下列基础包 //1. Redux状态管理 - reduxjs/toolkit 、 react-redux //2. 路由 - react-router-dom //3. 时间处理 - dayjs //4. class类名处理 - classnames //5. 移动端组件库 - antd-mobile //6. 请…

linux常见基础指令

入门常见基础指令 ls、stat、 pwd 、cd、tree、 whoami、 touch、 mkdir、 rm 、 man、 cp、mv、cat、tac、echo、>、 >>、 < 、more、 less、 head、 tail、date、 cal、 find、 which、alias、whereis、grep、zip与unzip、 tar、bc、uname、xargs... 热键Tab、…

【信息安全原理】——期末复习(冲刺篇)

&#x1f4d6; 前言&#xff1a;快考试了&#xff0c;做篇期末总结&#xff0c;都是重点与必考点。 题型&#xff1a;简答题&#xff08;45分&#xff09;、协议分析题&#xff08;210分&#xff09;&#xff08;给一个报文或工作流程&#xff0c;分析存在的问题&#xff09;、…

操作系统:linux(在虚拟机上详细步骤安装)Centos

文章目录 前言&#xff1a;一、如何在自己的电脑上安装centos?二、在虚拟机上安装centos2.1安装步骤&#xff1a; 前言&#xff1a; 操作系统有&#xff1a;windows server 不开源的收费的、linux 开源的免费的&#xff0c;精简安装&#xff08;没有UI)。国产的操作系统有&am…

Pytest框架 —— 用例标记和测试执行篇!

pytest用例标记和测试执行篇 上一篇文章入门篇咱们介绍了pytest的前后置方法和fixture机制&#xff0c;这个章节主要给大家介绍pytest中的标记机制和用例执行的方法。pytest可以通过标记将数据传入于测试函数中&#xff0c;也可以通过标记中对执行的用例做筛选&#xff0c;接下…

『亚马逊云科技产品测评』活动征文|云服务器如何快速搭建个人博客(图文详解)

授权声明&#xff1a;本篇文章授权活动官方亚马逊云科技文章转发、改写权&#xff0c;包括不限于在 Developer Centre, 知乎&#xff0c;自媒体平台&#xff0c;第三方开发者媒体等亚马逊云科技官方渠道 文章目录 引言一、前期准备步骤1.1 准备一个亚马逊 EC2 服务器1.2 进入控…

过年过节通过html+css+js代码实现:超级好看的放烟花效果(含背景音乐)

文章目录&#xff1a; 一&#xff1a;放烟花 1. 运行效果 2.代码 二&#xff1a;新年快乐 1.运行效果 2.代码 一&#xff1a;放烟花 1. 运行效果 效果图◕‿◕✌✌✌ 过年过节通过htmlcssjs实现放烟花效果代码(含背景音乐) 2.代码 修改后缀为".html"的格式…

数模混合SoC芯片中LEF2Milkyway的golden flow

在数模混合芯片中的项目中&#xff0c;特别是数字模块很少甚至只有一个简单的数字控制逻辑时&#xff0c;我们要做数字模块的后端实现时&#xff0c;通常模拟那边会问我们实现需要他们提供哪些数据。 通常来说&#xff0c;我们可以让模拟设计提供数字模块的GDS或LEF文件即可。…

QT中的信号与槽的讲解

文章目录 信号及其特点槽及其特点代码演示标准信号与标准槽函数方式一方式二 自定义信号和槽connect()函数信号和槽函数存在函数重载的情况下Qt的信号槽机制注意事项 信号及其特点 信号&#xff1a;是一种特殊的函数&#xff0c;又称信号函数&#xff0c;俗称信号&#xff0c;…

<软考高项备考>《论文专题 - 37 采购管理(1) 》

1 成本管理基础 1.1 写作要点 过程定义、作用写作要点、思路规划采购管理规划采购管理是记录项目采购决策、明确采购方法&#xff0c;及识别潜在卖方的过程。作用:确定是否从项目外部获取货物和服务&#xff0c;如果是&#xff0c;则还要确定将在什么时间、以什么方式获取什么…

项目实战--Message Queue

一. 概念篇 我们在学习多线程的时候,学习过生产者-消费者模型,为了实现解耦合和削峰填谷,引入了阻塞队列. 在实际的后端开发中,跨主机之间使用生产者消费者模型,也是非常普遍的需求,因此,阻塞队列会被封装成一个独立的服务器程序,实现更丰富的功能.这样的程序称为"消息队列…

Grafana监控数据可视化

Grafana 是一个可视化面板&#xff0c;有着非常漂亮的图表和布局展示&#xff0c;功能齐全的度量仪表盘和图形编辑器&#xff0c;支持 Graphite、zabbix、InfluxDB、Prometheus、OpenTSDB、Elasticsearch 等作为数据源&#xff0c;比 Prometheus 自带的图表展示功能强大太多&am…