天哪!Python实现自动驾驶!

2023年highway-env更新之后的使用记录(含DDQN,DuelingDQN,DDQN+OtherChanges) 入门到入土,再踩坑就不玩原神了 使用highway-env模拟自动驾驶汽车路况,深度强化学习算法设计智能体进行训练,避免汽车的碰撞。一些更新以及尝试。 阅读详情

点击上方“菜学Python”,选择“星标”公众号

c585fe9a67e004992ceb2738f8661a7a.jpeg

来源:blog.youkuaiyun.com/weixin_44169614?type=blog

一、安装环境

gym是用于开发和比较强化学习算法的工具包,在python中安装gym库和其中子场景都较为简便。

安装gym:

pip install gym

安装自动驾驶模块,这里使用Edouard Leurent发布在github上的包highway-env(链接:https://github.com/eleurent/highway-env):

pip install --user git+https://github.com/eleurent/highway-env

其中包含6个场景:

  • 高速公路——“highway-v0”

  • 汇入——“merge-v0”

  • 环岛——“roundabout-v0”

  • 泊车——“parking-v0”

  • 十字路口——“intersection-v0”

  • 赛车道——“racetrack-v0”

详细文档可以参考这里:

https://highway-env.readthedocs.io/en/latest/

二、配置环境

安装好后即可在代码中进行实验(以高速公路场景为例):

import gym
import highway_env
%matplotlib inline

env = gym.make('highway-v0')
env.reset()
for _ in range(3):
    action = env.action_type.actions_indexes["IDLE"]
    obs, reward, done, info = env.step(action)
    env.render()

运行后会在模拟器中生成如下场景:

9e5717b8b809481aef0db7ff9811bbad.png

绿色为ego vehicle env类有很多参数可以配置,具体可以参考原文档。

三、训练模型

1、数据处理

(1)state

highway-env包中没有定义传感器,车辆所有的state (observations) 都从底层代码读取,节省了许多前期的工作量。根据文档介绍,state (ovservations) 有三种输出方式:Kinematics,Grayscale Image和Occupancy grid。

Kinematics

输出V*F的矩阵,V代表需要观测的车辆数量(包括ego vehicle本身),F代表需要统计的特征数量。例:

34e98cd658e2c0e59598773b38db38a9.png

数据生成时会默认归一化,取值范围:[100, 100, 20, 20],也可以设置ego vehicle以外的车辆属性是地图的绝对坐标还是对ego vehicle的相对坐标。

在定义环境时需要对特征的参数进行设定:

config = \
    {
    "observation": 
         {
        "type": "Kinematics",
        #选取5辆车进行观察(包括ego vehicle)
        "vehicles_count": 5,  
        #共7个特征
        "features": ["presence", "x", "y", "vx", "vy", "cos_h", "sin_h"], 
        "features_range": 
            {
            "x": [-100, 100],
            "y": [-100, 100],
            "vx": [-20, 20],
            "vy": [-20, 20]
            },
        "absolute": False,
        "order": "sorted"
        },
    "simulation_frequency": 8,  # [Hz]
    "policy_frequency": 2,  # [Hz]
    }

Grayscale Image

生成一张W*H的灰度图像,W代表图像宽度,H代表图像高度

Occupancy grid

生成一个WHF的三维矩阵,用W*H的表格表示ego vehicle周围的车辆情况,每个格子包含F个特征。

(2) action

highway-env包中的action分为连续和离散两种。连续型action可以直接定义throttle和steering angle的值,离散型包含5个meta actions:

ACTIONS_ALL = {
        0: 'LANE_LEFT',
        1: 'IDLE',
        2: 'LANE_RIGHT',
        3: 'FASTER',
        4: 'SLOWER'
    }
(3) reward

highway-env包中除了泊车场景外都采用同一个reward function:

0ccd4099c12a3f9f7df0c61b6ef6f2a3.png

这个function只能在其源码中更改,在外层只能调整权重。(泊车场景的reward function原文档里有,懒得打公式了……)

2、搭建模型

DQN网络的结构和搭建过程已经在我另一篇文章中讨论过,所以这里不再详细解释。我采用第一种state表示方式——Kinematics进行示范。

由于state数据量较小(5辆车*7个特征),可以不考虑使用CNN,直接把二维数据的size[5,7]转成[1,35]即可,模型的输入就是35,输出是离散action数量,共5个。

import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.nn.functional as F
import torch.optim as optim
import torchvision.transforms as T
from torch import FloatTensor, LongTensor, ByteTensor
from collections import namedtuple
import random 
Tensor = FloatTensor

EPSILON = 0    # epsilon used for epsilon greedy approach
GAMMA = 0.9
TARGET_NETWORK_REPLACE_FREQ = 40       # How frequently target netowrk updates
MEMORY_CAPACITY = 100
BATCH_SIZE = 80
LR = 0.01         # learning rate

class DQNNet(nn.Module):
    def __init__(self):
        super(DQNNet,self).__init__()                  
        self.linear1 = nn.Linear(35,35)
        self.linear2 = nn.Linear(35,5)               
    def forward(self,s):
        s=torch.FloatTensor(s)        
        s = s.view(s.size(0),1,35)        
        s = self.linear1(s)
        s = self.linear2(s)
        return s           
                         
class DQN(object):
    def __init__(self):
        self.net,self.target_net = DQNNet(),DQNNet()        
        self.learn_step_counter = 0      
        self.memory = []
        self.position = 0 
        self.capacity = MEMORY_CAPACITY       
        self.optimizer = torch.optim.Adam(self.net.parameters(), lr=LR)
        self.loss_func = nn.MSELoss()

    def choose_action(self,s,e):
        x=np.expand_dims(s, axis=0)
        if np.random.uniform() < 1-e:  
            actions_value = self.net.forward(x)            
            action = torch.max(actions_value,-1)[1].data.numpy()
            action = action.max()           
        else: 
            action = np.random.randint(0, 5)
        return action

    def push_memory(self, s, a, r, s_):
        if len(self.memory) < self.capacity:
            self.memory.append(None)
        self.memory[self.position] = Transition(torch.unsqueeze(torch.FloatTensor(s), 0),torch.unsqueeze(torch.FloatTensor(s_), 0),\
                                                torch.from_numpy(np.array([a])),torch.from_numpy(np.array([r],dtype='float32')))#
        self.position = (self.position + 1) % self.capacity
       
    def get_sample(self,batch_size):
        sample = random.sample(self.memory,batch_size)
        return sample
      
    def learn(self):
        if self.learn_step_counter % TARGET_NETWORK_REPLACE_FREQ == 0:
            self.target_net.load_state_dict(self.net.state_dict())
        self.learn_step_counter += 1
        
        transitions = self.get_sample(BATCH_SIZE)
        batch = Transition(*zip(*transitions))

        b_s = Variable(torch.cat(batch.state))
        b_s_ = Variable(torch.cat(batch.next_state))
        b_a = Variable(torch.cat(batch.action))
        b_r = Variable(torch.cat(batch.reward))    
             
        q_eval = self.net.forward(b_s).squeeze(1).gather(1,b_a.unsqueeze(1).to(torch.int64)) 
        q_next = self.target_net.forward(b_s_).detach() #
        q_target = b_r + GAMMA * q_next.squeeze(1).max(1)[0].view(BATCH_SIZE, 1).t()           
        loss = self.loss_func(q_eval, q_target.t())        
        self.optimizer.zero_grad() # reset the gradient to zero        
        loss.backward()
        self.optimizer.step() # execute back propagation for one step       
        return loss
Transition = namedtuple('Transition',('state', 'next_state','action', 'reward'))

3、运行结果

各个部分都完成之后就可以组合在一起训练模型了,流程和用CARLA差不多,就不细说了。

初始化环境(DQN的类加进去就行了):

import gym
import highway_env
from matplotlib import pyplot as plt
import numpy as np
import time
config = \
    {
    "observation": 
         {
        "type": "Kinematics",
        "vehicles_count": 5,
        "features": ["presence", "x", "y", "vx", "vy", "cos_h", "sin_h"],
        "features_range": 
            {
            "x": [-100, 100],
            "y": [-100, 100],
            "vx": [-20, 20],
            "vy": [-20, 20]
            },
        "absolute": False,
        "order": "sorted"
        },
    "simulation_frequency": 8,  # [Hz]
    "policy_frequency": 2,  # [Hz]
    }
    
env = gym.make("highway-v0")
env.configure(config)

训练模型:

dqn=DQN()
count=0

reward=[]
avg_reward=0
all_reward=[]

time_=[]
all_time=[]

collision_his=[]
all_collision=[]
while True:
    done = False    
    start_time=time.time()
    s = env.reset()
    
    while not done:
        e = np.exp(-count/300)  #随机选择action的概率,随着训练次数增多逐渐降低
        a = dqn.choose_action(s,e)
        s_, r, done, info = env.step(a)
        env.render()
        
        dqn.push_memory(s, a, r, s_)
        
        if ((dqn.position !=0)&(dqn.position % 99==0)):
            loss_=dqn.learn()
            count+=1
            print('trained times:',count)
            if (count%40==0):
                avg_reward=np.mean(reward)
                avg_time=np.mean(time_)
                collision_rate=np.mean(collision_his)
                                
                all_reward.append(avg_reward)
                all_time.append(avg_time)
                all_collision.append(collision_rate)
                                
                plt.plot(all_reward)
                plt.show()
                plt.plot(all_time)
                plt.show()
                plt.plot(all_collision)
                plt.show()
                
                reward=[]
                time_=[]
                collision_his=[]
                
        s = s_
        reward.append(r)      
    
    end_time=time.time()
    episode_time=end_time-start_time
    time_.append(episode_time)
        
    is_collision=1 if info['crashed']==True else 0
    collision_his.append(is_collision)

我在代码中添加了一些画图的函数,在运行过程中就可以掌握一些关键的指标,每训练40次统计一次平均值。

平均碰撞发生率:

1037c0eed09973d1a82445028dff1d3e.png

epoch平均时长(s):

9d7bee2f8a3172e07fb1c100c5b8e092.png

平均reward:

408dc1c069ab28258c08690c0dc45e6a.png

可以看出平均碰撞发生率会随训练次数增多逐渐降低,每个epoch持续的时间会逐渐延长(如果发生碰撞epoch会立刻结束)

四、总结

相比于我在之前文章中使用过的模拟器CARLA,highway-env环境包明显更加抽象化,用类似游戏的表示方式,使得算法可以在一个理想的虚拟环境中得到训练,而不用考虑数据获取方式、传感器精度、运算时长等现实问题。对于端到端的算法设计和测试非常友好,但从自动控制的角度来看,可以入手的方面较少,研究起来不太灵活。

文末送书福利

我们每个月都会给大家包邮送书(累计送出433多本),常来留言混脸熟的都会有机会!这次送出的是"AI相关的"书籍 ,非常值得一读,有兴趣的同学可以看看。

062ef38f4047a54a141e251442e10a68.jpeg

区别于市场上同类书,本书不但侧重于理论知识的普及,也将技术融合于Python模块进行实验上的操作与演示。本书主要内容包括:人工智能技术概述,人脸识别技术、物体识别技术,视频识别技术、语音识别技术、文本识别技术,区块链技术等。全书综合了各种模块对人工智能技术的实践,将分散的技术点统一起来,并把抽象的原理与适应读者思维的案例相融合,实现知识点的充分理解。本书适合从事数据科学及AI的读者阅读。

如何获取:

包邮送5本,想要这本书或者其他的Python书籍的,可以在后台输入:小助手,暗号领书,我们抽奖送出,拼手气看人品,有兴趣来。

推荐阅读:
入门: 最全的零基础学Python的问题  | 零基础学了8个月的Python  | 实战项目 |学Python就是这条捷径
干货:爬取豆瓣短评,电影《后来的我们》 | 38年NBA最佳球员分析 |   从万众期待到口碑扑街!唐探3令人失望  | 笑看新倚天屠龙记 | 灯谜答题王 |用Python做个海量小姐姐素描图 |碟中谍这么火,我用机器学习做个迷你推荐系统电影
趣味:弹球游戏  | 九宫格  | 漂亮的花 | 两百行Python《天天酷跑》游戏!
AI: 会做诗的机器人 | 给图片上色 | 预测收入 | 碟中谍这么火,我用机器学习做个迷你推荐系统电影
小工具: Pdf转Word,轻松搞定表格和水印! | 一键把html网页保存为pdf!|  再见PDF提取收费! | 用90行代码打造最强PDF转换器,word、PPT、excel、markdown、html一键转换 | 制作一款钉钉低价机票提示器! |60行代码做了一个语音壁纸切换器天天看小姐姐!|


点阅读原文,看B站我的视频!

用于强化学习的自动驾驶仿真场景highway-env(1) 在强化学习过程中,一个可交互,可定制,直观的交互场景必不可少。 最近发现一个自动驾驶的虚拟环境,本文主要来说明下如何使用该environment 具体项目的github地址 一、 定制环境 quickly experience 如下代码可以快速创建一个env import gym import highway_env from matplotlib import pyplot as plt env = gym.make('highway-v0') env.reset() for _ in range( 阅读详情

相关推荐

天哪,用Python实现自动驾驶

一、安装环境 gym是用于开发和比较强化学习算法的工具包,在python中安装gym库和其中子场景都较为简便。 安装gym:

y1282037271的博客 318

python编程人工智能小例子,python人工智能算法代码

1、人生苦短,我用Python:简单、高效、易入门在讨论为什么选择Python之前我们首先得知道Python是个什么东西。Python是一种面向对象、解释型计算机程序设计语言。它的设计初衷就是优雅、明确、简单。比起同样是面向对象的Java语言,函数、模块、字符串、数字对于Python来说全都是对象,而不像Java中还有基本类型一说。有些小伙伴可能要问了,Python作为脚本语言,运行速度没有Java和c++快,为什么还要选择Python。人工智能的核心计算全是C语言写好的底层,Python只是写逻辑。

神器榜 1万+

天哪,花姐用Python写了个双色球号码生成程序,竟中了200元

如果你也想挑战一下自己,写一个类似的小程序,或者干脆来个有趣的编程小项目,记得分享给我哦!如果你已经学会了如何用Python写个彩票抽奖程序,那恭喜你,已经开始走向编程大牛的路了!如果你有什么想分享给大家的文章,只要是关于Python方面的都随时欢迎大家投稿!🎉。

奔跑的蜗牛 3085

highway-env自定义高速路环境

highway-env自定义高速路环境

ColinFhz的博客 4515

highway-env:自动驾驶决策的极简环境

高速公路环境 自动驾驶和战术决策任务的环境集合 高速公路环境中可用环境之一的一集。 环境 高速公路 env = gym . make ( "highway-v0" ) 在这项任务中,自我车辆正在一条多车道高速公路上行驶,该高速公路上挤满了其他车辆。 代理的目标是达到高速,同时避免与相邻车辆发生碰撞。 在道路右侧行驶也有奖励。 高速公路-v0 环境。 合并 env = gym . make ( "merge-v0" ) 在这项任务中,自我车辆从主干道开始,但很快就会接近路口,进入坡道上的车辆。 代理现在的目标是保持高速,同时为车辆腾出空间,以便它们可以安全地并入交通。 merge-v0 环境。 迂回 env = gym . make ( "roundabout-v0" ) 在此任务中,自我车辆是否接近交通流量较大的环形交叉路口。 它将自动遵循其计划路线,但必须处理车

Qt绘图库对决:QWT与QCustomPlot的实战选型指南

本文为Qt开发者提供了QWT与QCustomPlot两大绘图库的实战选型指南。文章从功能特性、性能资源、开发效率三大维度进行深度对比,并结合工业监控、科学计算、嵌入式设备等典型场景,给出了清晰的决策清单。对于需要专业科学图表(如极坐标、等高线图)的场景推荐QWT;对于追求高性能、实时性、快速开发及嵌入式部署的通用图表需求,QCustomPlot是更优选择。

alpha的博客 241

天哪!用Python实现自动驾驶!

相比于我在之前文章中使用过的模拟器CARLA,highway-env环境包明显更加抽象化,用类似游戏的表示方式,使得算法可以在一个理想的虚拟环境中得到训练,而不用考虑数据获取方式、传感器精度、运算时长等现实问题。对于端到端的算法设计和测试非常友好,但从自动控制的角度来看,可以入手的方面较少,研究起来不太灵活。

2401_86168842的博客 1588

1.47寸ST7789V3彩屏硬件设计与驱动调试指南

TFT LCD是一种基于薄膜晶体管阵列控制像素明暗的主动式显示技术,其核心依赖于专用驱动IC(如ST7789V3)完成时序生成、GRAM管理与伽马校正。该类小尺寸彩色显示屏广泛应用于嵌入式HMI、IoT终端与可穿戴设备,具备高PPI、低功耗和SPI接口易集成等工程优势。理解RGB565数据格式、SPI Mode 0通信时序及关键寄存器(如0x36方向控制、0x3A像素格式、0x2A/0x2B地址窗口)是实现稳定显示的基础;而正确处理电源设计(严禁5V直供)、复位时序与背光PWM调光,则直接决定系统可靠性与能

weixin_30995917的博客 165

如何用python写 翻译腔?天哪~这实在是太有趣了~

“我的老伙计,说真的,真是活见鬼。我们为什么不坐下喝杯咖啡呢?天哪,我的老天啊,上帝会喜欢的,您瞧瞧,这个问题实在是太糟糕了,噢!就像隔壁苏珊婶婶做的苹果派一样。 ”

m0_67575344的博客 7615

获取车辆VIN等OBD信息

获取车辆如下OBD信息: VIN:Vehicle Identification Number CALID:Calibration Identifications CVN:Calibration verification number 一、SAE J1939协议 通过请求 CALIBRATION INFORMATION (DM19),获取CVN和CALID。 发送请求:18EA00F9 00 D3 00 应答:18EC0000 10 14 00 03 FF 00 D3 00 数据,BYTE1=0x10,表明

jianxuezixuan的博客 1万+

历年CSP-J(NOIP普及组)考点分析与分类汇总(纯干货)

noip/csp-j历年真题考点分类

weixin_42358969的博客 1万+

天哪,Python居然支持中文变量

不仅是普通变量,列表和字典也支持喔。

Enjoy_Python的博客 465

V-REP(Cooprliesim EDU)自学笔记 实现UR5机械臂末端按轨迹移动

V-REP(Cooprliesim EDU)自学笔记 实现UR5机械臂末端按轨迹移动

xu_white的博客 7583

我的天哪,Python这个岗位月薪10W+

无意中看到Python相关职位,竟然看到一个月薪10W的岗位,再翻一翻,3W5W甚至7W8W的比比皆是,这些个工资真是慕了慕了看到这些岗位才发现,原来做个技术大牛可以这么赚钱!不说了,继续去肝我的Python了!

m0_59235245的博客 160

《QGIS快速入门与应用基础》021:插件仓库 URL 获取与添加

详细介绍了在QGIS中添加第三方插件仓库的方法。首先强调必须从官方推荐、开源社区等可靠渠道获取插件仓库URL以确保安全性,并列出了4类可信获取渠道。文章分步骤讲解了URL添加流程,包括打开插件管理器设置面板、填写仓库信息、刷新缓存验证等操作。针对常见问题如URL格式错误、连接失败等提供了具体解决方案。最后总结指出,成功添加第三方仓库后即可直接搜索安装各类专业插件,从而扩展QGIS功能边界。全文注重实操指导,特别适合需要安装行业专用插件的QGIS用户参考。

LuckyHanMo的博客 463

基于simulink的智能驾驶领域--智能车道保持辅助系统仿真

LKAS通过摄像头等传感器检测车辆相对于车道线的位置,并自动调整转向,以帮助驾驶员保持在车道内行驶。将摄像头传感器模块的输出连接到车道线检测模块的输入端口,再将车道线检测模块的输出连接到转向控制器模块的输入端口,最后将转向控制器模块的输出连接到车辆动力学模型的转向输入端口,形成闭环控制系统。上升时间是指系统从初始转向角上升到目标转向角所需的时间,调节时间是指系统进入并保持在目标转向角一定范围内的所需时间。该控制器将根据摄像头传感器的数据调整车辆的转向角,以保持车辆在车道内行驶。

xiaoheshang_123的博客 161

天哪!递归竟然如此简单!

代码递归解决Python经典算法

NOVICE423的博客 212

【异常】解决 Cursor 报错 Unexpected seqno: 2 != 1. Please try again, or contact support if the issue 的排坑指南

在使用 Cursor 辅助编程时,你是否遇到过 AI 突然中断输出,并在右下角弹出一个红色的 Network Error 弹窗?今天我们就来彻底解析并解决这个网络断连问题。

奶爸的编程之路,也就一周冷个三天 2470

java ruby_Java,Ruby和Go,我的天哪!

java rubyFree Code Camp has focused 100% on full stack JavaScript since we started 17 months ago. We’ve taught JavaScript on the front end, JavaScript on the back end (thanks to the powerful Node.js f...

316

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

我的天哪,Python数据处理脚本获得4倍提速,只用了3行代码

Python是一门非常适合处理数据和自动化完成重复性工作的编程语言,我们在用数据训练机器学习模型之前,通常都需要对数据进行预处理,而Python就非常适合完成这项工作,比如需要重新调整几十万张图像的尺寸,用Python没问题!你几乎总是能找到一款可以轻松完成数据处理工作的Python库。然而,虽然Python易于学习,使用方便,但它并非运行速度最快的语言。默认情况下,Python程序使用一个CPU...

weixin_34200628的博客 511

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

我的天哪!大一新生开发的Python小工具火了,网友:我好菜啊

前文 普普通通黑底白字地敲代码太枯燥?那么,把Python脚本可视化怎么样?就像这样,从输入图片、调整尺寸到双边滤波,每一步都能看得清清楚楚明明白白。 输入一个矩阵,无论是对它进行转置、求共轭还是乘方,都能得到及时的反馈。 这样一个Python脚本可视化工具,名叫Ryven,出自一位名叫Leon Thomm的大一新生之手。如果你也想试用一番,不妨接着往下看。 如何使用 使用之前,简单准备一下开发环境: Python3(推荐3.8以上) PySide2(推荐2.14以上) ...

PC_372的博客 229

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

秘闻 | 我的天哪!1024居然发生了这些事...

本篇推文共计1100个字,阅读时间约2分钟。1024程序员节是广大程序员的共同节日。1024是2的十次方,二进制计数的基本计量单位之一。针对程序员经常周末加班与工作日熬夜的情况,部分互联...

看那个码农的博客 1542
上一篇: 时隔37年,Windows 11更换系统默认终端!
下一篇: 太全了!用Python操作MySQL的使用教程集锦!
菜鸟学Python
博客等级 码龄9年 8042粉丝 571原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值