Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Belajar Python untuk melaksanakan sistem pemanduan autonomi

Belajar Python untuk melaksanakan sistem pemanduan autonomi

王林
王林ke hadapan
2023-04-21 16:58:081142semak imbas

Belajar Python untuk melaksanakan sistem pemanduan autonomi

Persekitaran Pemasangan

gim ialah kit alat untuk membangunkan dan membandingkan algoritma pembelajaran tetulang Agak mudah untuk memasang perpustakaan gim dan sub-senarionya dalam python.

Pasang gim:

pip install gym

Pasang modul pemanduan autonomi, di sini kami menggunakan pakej highway-env yang diterbitkan oleh Edouard Leurent di github:

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

Ia mengandungi 6 Scene:

  • Lebuhraya - "highway-v0"
  • Cantum - "merge-v0"
  • Bulatan - "roundabout-v0"
  • Tempat letak kereta - "parking-v0"
  • Persimpangan - "intersection-v0"
  • Trek lumba - "racetrack-v0"

Dokumentasi terperinci boleh didapati di sini :

​https://www.php.cn/link/c0fda89ebd645bd7cea60fcbb5960309​

Persekitaran konfigurasi

Selepas pemasangan dalam kod (ambil pemandangan lebuh raya sebagai contoh):

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()

Selepas berjalan, pemandangan berikut akan dijana dalam simulator:

Belajar Python untuk melaksanakan sistem pemanduan autonomi

Kelas env mempunyai banyak parameter yang boleh dikonfigurasikan Untuk butiran, sila rujuk dokumen asal.

Model latihan

1 Pemprosesan data

(1) keadaan

Tiada penderia yang ditakrifkan dalam pakej lebuh raya-env, dan semua keadaan ( pemerhatian) kenderaan adalah Semua dibaca daripada kod asas, menjimatkan banyak kerja awal. Menurut dokumentasi, keadaan (ovservations) mempunyai tiga kaedah output: Kinematik, Imej Skala Kelabu dan Grid Penghuni.

Kinematik

Keluaran matriks V*F, V mewakili bilangan kenderaan yang perlu diperhatikan (termasuk kenderaan ego itu sendiri), dan F mewakili bilangan ciri yang perlu dikira. Contoh:

Data akan dinormalkan secara lalai apabila dijana Julat nilai ialah: [100, 100, 20, 20]. Anda juga boleh menetapkan atribut kenderaan selain daripada kenderaan ego sebagai koordinat mutlak peta atau relatif kepada kenderaan ego.

Apabila mentakrifkan persekitaran, anda perlu menetapkan parameter ciri:

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]
}

Imej Skala Kelabu

Janakan imej skala kelabu W*H, dengan W mewakili Lebar imej, H mewakili ketinggian imej

Grid penghunian

menjana matriks tiga dimensi WHF, menggunakan jadual W*H untuk mewakili keadaan kenderaan di sekeliling kenderaan ego ciri F.

(2) tindakan

Tindakan dalam pakej lebuh raya-env dibahagikan kepada dua jenis: berterusan dan diskret. Tindakan berterusan boleh menentukan secara langsung nilai pendikit dan sudut stereng Tindakan diskret mengandungi 5 tindakan meta:

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

(3) ganjaran

Selain tempat letak kereta, pakej highway-env Mereka semua menggunakan fungsi ganjaran yang sama:

Belajar Python untuk melaksanakan sistem pemanduan autonomi

Fungsi ini hanya boleh ditukar dalam kod sumbernya dan berat hanya boleh dilaraskan di lapisan luar .

(Fungsi ganjaran tempat letak kereta disertakan dalam dokumen asal)

2 Bina model

Rangkaian DQN, saya menggunakan kaedah perwakilan keadaan pertama - Kinematics untuk demonstrasi. Memandangkan jumlah data keadaan adalah kecil (5 kereta * 7 ciri), anda boleh mengabaikan penggunaan CNN dan terus menukar saiz [5,7] data dua dimensi kepada [1,35]. model ialah 35. Output ialah bilangan tindakan diskret, 5 kesemuanya.

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. Hasil larian

Selepas setiap bahagian selesai, model boleh digabungkan untuk melatih model ini, jadi saya tidak akan melakukannya pergi ke butiran.

Mulakan persekitaran (hanya tambah kelas 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)

Model latihan:

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)

Saya menambah beberapa fungsi lukisan pada kod beberapa petunjuk utama semasa operasi, dan hitung nilai purata setiap 40 kali latihan.

Purata kadar perlanggaran:

Belajar Python untuk melaksanakan sistem pemanduan autonomi

Purata tempoh (s):

Belajar Python untuk melaksanakan sistem pemanduan autonomi

Purata ganjaran :

Belajar Python untuk melaksanakan sistem pemanduan autonomi

Adalah dapat dilihat bahawa purata kadar insiden perlanggaran akan berkurangan secara beransur-ansur apabila bilangan masa latihan meningkat, dan tempoh setiap zaman akan beransur-ansur dilanjutkan (jika perlanggaran berlaku , zaman akan tamat serta-merta)

Ringkasan

Berbanding dengan simulator CARLA, pakej persekitaran lebuh raya dengan ketara lebih abstrak Ia menggunakan perwakilan seperti permainan supaya algoritma boleh terlatih dalam persekitaran maya yang ideal Tidak perlu mempertimbangkan isu praktikal seperti kaedah pemerolehan data, ketepatan penderia dan masa pengiraan. Ia sangat mesra untuk reka bentuk dan ujian algoritma hujung ke hujung, tetapi dari perspektif kawalan automatik, terdapat lebih sedikit aspek untuk dimulakan dan ia tidak begitu fleksibel untuk diselidik.

Atas ialah kandungan terperinci Belajar Python untuk melaksanakan sistem pemanduan autonomi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:51cto.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam