端到端自動駕駛——cnn網絡搭建

論文參考:https://arxiv.org/abs/1604.07316
demo
在這里插入圖片描述

今天主要來看一個如何通過圖像直接到控制的自動駕駛端到端的項目,首先需要配置好我的仿真環境,下載軟件udacity:
https://d17h27t6h515a5.cloudfront.net/topher/2016/November/5831f3a4_simulator-windows-64/simulator-windows-64.zip

現在好的解壓即可
在這里插入圖片描述
運行時打開終端,然后將文件拖入終端中運行
在這里插入圖片描述
選擇合適的窗口大小
在這里插入圖片描述
成功進入界面
在這里插入圖片描述
然后配置一下python環境,對于已經有conda環境后,直接

conda create -n cnn python=3.8
conda activate cnn

安裝以下依賴:

astor==0.8.1
bidict==0.21.2
certifi==2021.5.30
charset-normalizer==2.0.4
click==8.0.1
colorama==0.4.4
cycler==0.10.0
decorator==5.0.9
dnspython==1.16.0
eventlet==0.31.1
Flask==2.0.1
gast==0.3.3
greenlet==1.1.0
idna==3.2
itsdangerous==2.0.1
Jinja2==3.0.1
joblib==1.0.1
kiwisolver==1.3.1
MarkupSafe==2.0.1
matplotlib==3.4.2
numpy==1.19.3
opencv-python==4.5.3.56
paddlepaddle==2.1.2
pandas==1.3.1
Pillow==8.3.1
protobuf==3.17.3
pyparsing==2.4.7
python-dateutil==2.8.2
python-engineio==3.13.0
python-socketio==4.6.1
pytz==2021.1
requests==2.26.0
scikit-learn==0.24.2
scipy==1.7.1
six==1.16.0
threadpoolctl==2.2.0
urllib3==1.26.6
Werkzeug==2.0.1

代碼

git clone https://github.com/chan-yuu/end_to_end_ws.git

數據集可以自己駕駛udacity的車輛收集,也可以直接下載下來訓練師需要指定文件夾的路徑,這里我使用的是一個csv文件來指定我的文件夾
主要文件放置的結構要寫入csv文件中,分別是左中右的攝像頭圖片路徑,方向盤,油門,剎車,速度信息。
打開仿真環境,進入training模式
在這里插入圖片描述
通過鍵盤即可控制車輛運行。
可以點擊record記錄這個過程中的數據,之后就能自動生成需要的數據集內容

python train

python train.py -d xxx.csv

我仔細研讀了一下這個代碼

import paddle
import argparse
import numpy as np
import paddle.nn as nnfrom paddle.optimizer import Adam
from paddle.callbacks import ModelCheckpoint, EarlyStoppingfrom car.model import build_model
from car.utils import CarDataset, load_data# 設置隨機種子,確保結果可復現
np.random.seed(0)def train_model(model, args, X_train, X_valid, y_train, y_valid):"""Train the model"""# 創建一個模型檢查點回調,用于在訓練過程中保存模型checkpoint = ModelCheckpoint(save_dir=args.save_dir)# 創建一個早停回調,當監控的指標(這里是損失值)在一定輪數(patience)內沒有改善時,停止訓練earlystopping = EarlyStopping(monitor='loss',mode='min',  # 監控損失值,希望其越小越好patience=10,  # 允許損失值在 10 個 epoch 內沒有改善verbose=1,  # 打印早停信息min_delta=0,  # 損失值的最小改善量baseline=None,  # 基線值,這里不使用save_best_model=True)  # 保存最佳模型# 根據命令行參數決定是否使用早停回調if args.early_stop:cbs = [checkpoint, earlystopping]else:cbs = [checkpoint]# 創建 Adam 優化器,用于更新模型的參數opt = Adam(learning_rate=args.learning_rate, parameters=model.parameters())# 將模型包裝為 paddle.Model 對象,方便進行訓練和評估model = paddle.Model(model)# 配置模型的損失函數和優化器model.prepare(loss=nn.MSELoss(), optimizer=opt)# 創建訓練數據集對象train_dataset = CarDataset(args.data_dir, X_train, y_train, True)# 創建驗證數據集對象val_dataset = CarDataset(args.data_dir, X_valid, y_valid, False)# 開始訓練模型model.fit(train_data=train_dataset,  # 訓練數據集eval_data=val_dataset,  # 驗證數據集epochs=args.nb_epoch,  # 訓練的輪數batch_size=args.batch_size,  # 每個批次的樣本數量save_dir=args.save_dir,  # 模型保存的目錄callbacks=cbs,  # 回調函數列表verbose=1)  # 打印訓練進度信息def s2b(s):"""Converts a string to boolean value"""# 將字符串轉換為小寫s = s.lower()# 判斷字符串是否表示真return s == 'true' or s == 'yes' or s == 'y' or s == '1'def main():"""Load train/validation data set and train the model"""# 創建命令行參數解析器parser = argparse.ArgumentParser(description='Behavioral Cloning Training Program')# 添加數據目錄參數,默認值為 'data'parser.add_argument('-d',help='data directory',dest='data_dir',type=str,default='data')# 添加模型保存目錄參數,默認值為 'save'parser.add_argument('-s',help='save directory',dest='save_dir',type=str,default='save')# 添加測試集大小比例參數,默認值為 0.2parser.add_argument('-t',help='test size fraction',dest='test_size',type=float,default=0.2)# 添加 Dropout 概率參數,默認值為 0.5parser.add_argument('-k',help='drop out probability',dest='keep_prob',type=float,default=0.5)# 添加訓練輪數參數,默認值為 100parser.add_argument('-n',help='number of epochs',dest='nb_epoch',type=int,default=100)# 添加批次大小參數,默認值為 40parser.add_argument('-b',help='batch size',dest='batch_size',type=int,default=40)# 添加學習率參數,默認值為 1.0e-4parser.add_argument('-l',help='learning rate',dest='learning_rate',type=float,default=1.0e-4)# 添加早停參數,默認值為 Falseparser.add_argument('-e',help='early stop',dest='early_stop',type=bool,default=False)# 解析命令行參數args = parser.parse_args()print('-' * 30)print('Parameters')print('-' * 30)# 打印所有命令行參數for key, value in vars(args).items():print('{:<20} := {}'.format(key, value))print('-' * 30)# 加載訓練數據和驗證數據data = load_data(args)# 構建模型model = build_model(args.keep_prob)# 調用訓練函數進行模型訓練train_model(model, args, *data)if __name__ == '__main__':# 程序入口,調用 main 函數main()

訓練結束后可以得到對應的模型
在這里插入圖片描述
使用這個模型進行測試
打開仿真軟件的auto模式
在這里插入圖片描述

此時是無法記錄的,然后我可以加載模型并駕駛車輛

python drive.py ./pretrained_models/model_paddle_test2.pdparams

同樣,自己寫一邊這個代碼更容易理解:

import os
import base64
import paddle
import shutil
import argparse
import socketio
import eventlet
import numpy
import eventlet.wsgi
from PIL import Imagefrom io import BvtesIO
from flask import Flask
from datatime import datatime
from car.model import build_model
from car.utils import preprocess# 創建一個socket.IO服務器
sio = socket.Server()
app = Flask(__name__)
# 初始化模型變量,用于后續加載模型
model = None
# 初始化上一幀圖像數組變量,用于記錄上一幀的圖像數據
prev_image_array = None# 定義最大速度和最小速度
MAX_SPEED = 25
MIN_SPEED = 10# 初始化速度限制為最大速度
speed_limit = MAX_SPEED# 定義一個事件處理函數,當接收到 'telemetry' 事件時觸發
@sio.on('telemetry')
def telemetry(sid, data):if data:# 從接收到的數據中提取當前汽車的轉向角度steering_angle = float(data["steering_angle"])# 從接收到的數據中提取當前汽車的油門值throttle = float(data["throttle"])# 從接收到的數據中提取當前汽車的速度speed = float(data["speed"])# 從接收到的數據中提取當前汽車中心攝像頭的圖像,并將其解碼為 PIL 圖像對象image = Image.open(BytesIO(base64.b64decode(data["image"])))# 如果指定了圖像保存文件夾,則保存當前幀圖像if args.image_folder != '':# 生成當前時間戳,用于作為圖像文件名timestamp = datetime.utcnow().strftime('%Y_%m_%d_%H_%M_%S_%f')[:-3]# 構建圖像文件的完整路徑image_filename = os.path.join(args.image_folder, timestamp)# 保存圖像為 JPEG 格式image.save('{}.jpg'.format(image_filename))try:# 將 PIL 圖像對象轉換為 NumPy 數組image = np.asarray(image)# 對圖像進行預處理,例如裁剪、歸一化等操作image = preprocess(image)# 為圖像數組添加一個維度,使其成為 4D 數組,以滿足模型輸入要求image = np.array([image])# 使用模型對圖像進行預測,得到轉向角度的預測值steering_angle = model(image.astype('float32') / 127.5 - 1.0).item()# 根據當前速度調整速度限制和油門值global speed_limitif speed > speed_limit:# 如果當前速度超過速度限制,則將速度限制降低到最小速度,以減速speed_limit = MIN_SPEEDelse:# 如果當前速度低于速度限制,則將速度限制恢復到最大速度speed_limit = MAX_SPEED# 根據轉向角度和速度計算油門值throttle = 1.0 - steering_angle**2 - (speed / speed_limit)**2# 打印當前的轉向角度、油門值和速度print(f'steering_angle={steering_angle:.3f}, throttle={throttle:.3f}, speed={speed:.3f}')# 發送控制指令,包括轉向角度和油門值send_control(steering_angle, throttle)except Exception as e:# 打印異常信息print(e)else:# 如果沒有接收到數據,則發送手動控制指令sio.emit('manual', data={}, skip_sid=True)# 定義一個事件處理函數,當有新的客戶端連接時觸發
@sio.on('connect')
def connect(sid, environ):# 打印連接信息print("connect ", sid)# 發送初始控制指令,將轉向角度和油門值都設為 0send_control(0, 0)# 定義一個函數,用于發送控制指令
def send_control(steering_angle, throttle):# 向客戶端發送 'steer' 事件,包含轉向角度和油門值sio.emit("steer",data={'steering_angle': steering_angle.__str__(),'throttle': throttle.__str__()},skip_sid=True)if __name__ == '__main__':# 創建一個命令行參數解析器parser = argparse.ArgumentParser(description='Remote Driving')# 添加一個必需的命令行參數,用于指定模型文件的路徑parser.add_argument('model',type=str,help='Path to model h5 file. Model should be on the same path.')# 添加一個可選的命令行參數,用于指定圖像保存文件夾的路徑parser.add_argument('image_folder',type=str,nargs='?',default='',help='Path to image folder. This is where the images from the run will be saved.')# 解析命令行參數args = parser.parse_args()# 構建模型model = build_model()# 加載模型的參數params = paddle.load(args.model)# 將加載的參數設置到模型中model.set_dict(params)# 將模型轉換為靜態圖模式,以提高推理速度model = paddle.jit.to_static(model)# 將模型設置為評估模式model.eval()# 如果指定了圖像保存文件夾if args.image_folder != '':# 打印創建圖像文件夾的信息print("Creating image folder at {}".format(args.image_folder))# 如果文件夾不存在,則創建它if not os.path.exists(args.image_folder):os.makedirs(args.image_folder)else:# 如果文件夾已存在,則先刪除它,再重新創建shutil.rmtree(args.image_folder)os.makedirs(args.image_folder)# 打印記錄運行信息print("RECORDING THIS RUN ...")else:# 如果沒有指定圖像保存文件夾,則打印不記錄運行信息print("NOT RECORDING THIS RUN ...")# 使用 Socket.IO 中間件包裝 Flask 應用app = socketio.Middleware(sio, app)# 使用 eventlet 啟動一個 WSGI 服務器,監聽 4567 端口eventlet.wsgi.server(eventlet.listen(('', 4567)), app)

在這里插入圖片描述

即可實現基于視覺的自動駕駛功能。后面這篇文章還會繼續完善論文中的一些觀點和代碼的一些學習過程。
https://github.com/naokishibuya/car-behavioral-cloning?tab=readme-ov-file

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72336.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72336.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72336.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

藍橋杯試題:二分查找

一、問題描述 給定 n 個數形成的一個序列 a&#xff0c;現定義如果一個連續子序列包含序列 a 中所有不同元素&#xff0c;則該連續子序列便為藍橋序列&#xff0c;現在問你&#xff0c;該藍橋序列長度最短為多少&#xff1f; 例如 1 2 2 2 3 2 2 1&#xff0c;包含 3 個不同的…

網絡空間安全(7)攻防環境搭建

一、搭建前的準備 硬件資源&#xff1a;至少需要兩臺計算機&#xff0c;一臺作為攻擊機&#xff0c;用于執行攻擊操作&#xff1b;另一臺作為靶機&#xff0c;作為被攻擊的目標。 軟件資源&#xff1a; 操作系統&#xff1a;如Windows、Linux等&#xff0c;用于安裝在攻擊機和…

DeepSpeek服務器繁忙?這幾種替代方案幫你流暢使用!(附本地部署教程)

作者&#xff1a;后端小肥腸 目錄 1. 前言 2. 解決方案 2.1. 納米AI搜索&#xff08;第三方平臺&#xff09; 2.2. Github&#xff08;第三方平臺&#xff09; 2.3. 硅基流動&#xff08;第三方API&#xff09; 3. 本地部署詳細步驟 3.1. 運行配置需求 3.2. 部署教程 4…

prisma+supabase報錯無法查詢數據

解決方案&#xff0c;在DATABASE_URL后面增加?pgbouncertrue

c語言中return 數字代表的含義

return 數字的含義&#xff1a;表示函數返回一個整數值&#xff0c;通常用于向調用者&#xff08;如操作系統或其他程序&#xff09;傳遞程序的執行狀態或結果。 核心規則&#xff1a; return 0&#xff1a; 含義&#xff1a;表示程序或函數正常結束。 示例&#xff1a; int m…

Spark內存迭代計算

一、寬窄依賴 窄依賴&#xff1a;父RDD的一個分區數據全部發往子RDD的一個分區 寬依賴&#xff1a;父RDD的一個分區數據發往子RDD的多個分區&#xff0c;也稱為shuffle 二、Spark是如何進行內存計算的&#xff1f;DAG的作用&#xff1f;Stage階段劃分的作用&#xff1f; &a…

Linux知識-第一天

Linux的目錄機構為一個樹型結構 其沒有盤符這個概念&#xff0c;只有一個根目錄&#xff0c;所有文件均在其之下 在Linux系統中&#xff0c;路徑之間的層級關系 使用 / 開頭表示根目錄&#xff0c;后面的表示層級關系 Linux命令入門 Linux命令基礎 Linux命令通用格式 comman…

QT實現單個控制點在曲線上的貝塞爾曲線

最終效果: 一共三個文件 main.cpp #include <QApplication> #include "SplineBoard.h" int main(int argc,char** argv) {QApplication a(argc, argv);SplineBoard b;b.setWindowTitle("標準的貝塞爾曲線");b.show();SplineBoard b2(0.0001);b2.sh…

繪制思維導圖畫布選型

在實現思維導圖/知識圖譜的繪制時&#xff0c;選擇合適的「畫布」技術方案至關重要。以下是不同技術路線的對比分析和推薦方案&#xff1a; 一、技術方案對比 技術類型實現方式優點缺點適用場景普通DOM元素使用<div>CSS布局&#x1f539; 開發簡單&#x1f539; 天然支持…

運維Splunk面試題及參考答案

目錄 通過轉發器導入數據的優勢有哪些(如帶寬控制、負載均衡等) 描述 Universal Forwarder 與 Heavy Forwarder 的差異 如何配置轉發器實現數據的過濾與預處理 轉發器的本地緩存機制如何保證數據可靠性 如何通過部署服務器統一管理多個轉發器的配置 什么是 “查找表(L…

年后寒假總結及計劃安排

年后寒假總結 年后主要學習了微服務&#xff0c;nacos (服務注冊中心)&#xff0c;feign&#xff08;遠程調用&#xff09;&#xff0c;網關&#xff0c;雙token&#xff08;相較于之前更加規范&#xff0c;更加符合企業級&#xff09;&#xff0c;配置管理 &#xff0c;mybati…

word中交叉引用多篇參考文獻格式[1-2]或[1-4]操作

劃重點 更改左域名&#xff0c;輸入 \#"[0" 更改中間域名&#xff0c;輸入\#"" 更改右域名&#xff0c;輸入 \#"0]" 1.[2-3]格式 首先點擊交叉引用&#xff0c;引用參考文獻 右擊鼠標&#xff0c;點擊切換域代碼&#xff0c;對于左域名 刪除 * …

【銀河麒麟高級服務器操作系統】服務器測試業務耗時問題分析及處理全流程分享

更多銀河麒麟操作系統產品及技術討論&#xff0c;歡迎加入銀河麒麟操作系統官方論壇 https://forum.kylinos.cn 了解更多銀河麒麟操作系統全新產品&#xff0c;請點擊訪問 麒麟軟件產品專區&#xff1a;https://product.kylinos.cn 開發者專區&#xff1a;https://developer…

opencv 模板匹配方法匯總

在OpenCV中&#xff0c;模板匹配是一種在較大圖像中查找特定模板圖像位置的技術。OpenCV提供了多種模板匹配方法&#xff0c;通過cv2.matchTemplate函數實現&#xff0c;該函數支持的匹配方式主要有以下6種&#xff0c;下面詳細介紹每種方法的原理、特點和適用場景。 1. cv2.T…

NAT,代理服務,內網穿透

NAT 把報文的源IP替換為途徑路由器的WAN口IP NAPT 如何將數據從公網轉回給內網的主機&#xff1f;通過NAPT&#xff08;轉換表&#xff09;來實現&#xff0c;每次從內網到公網&#xff0c;公網到內網都會根據轉換表來進行 細節&#xff1a; NAT轉換時&#xff0c;值替換源…

大模型分布式訓練和優化

1. 分布式訓練概述 隨著語言模型參數量和所需訓練數據量的急速增長,單個機器上有限的資源已無法滿足大語言模型訓練的要求。因此,設計分布式訓練(Distributed Training)系統來解決海量的計算和內存資源需求問題變得至關重要。 分布式訓練是指將機器學習或深度學習模型訓練任…

第三方機構有哪些接口?

1&#xff0c;網銀接口。2&#xff0c;代扣接口。3&#xff0c;POS接口。4&#xff0c;快捷支付接口 1.網銀接口 第三方支付平臺連接網銀接口&#xff0c;進行支付跳轉時&#xff0c;第三方支付平臺充當了一個網關的角色&#xff0c;或者充當了銀行的代 理。 2.代扣接口 銀…

JUnit 版本影響 Bean 找不到

JUnit 版本影響 Bean 找不到 在為實現類編寫測試類時&#xff0c;在測試類中使用構造器注入 Bean 時&#xff0c;提示找不到 Bean&#xff0c;代碼如下&#xff1a; Service public class WeChatServiceImpl implements IWeChatService {Overridepublic String getNumber(Str…

夸父工具箱(安卓版) 手機超強工具箱

如今&#xff0c;人們的互聯網活動日益頻繁&#xff0c;導致手機內存即便頻繁清理&#xff0c;也會莫名其妙地迅速填滿&#xff0c;許多無用的垃圾信息悄然占據空間。那么&#xff0c;如何有效應對這一難題呢&#xff1f;答案就是今天新推出的這款工具軟件&#xff0c;它能從根…

《深度學習進階》第7集:深度實戰 通過訓練一個智能體玩游戲 來洞察 強化學習(RL)與決策系統

深度學習進階 | 第7集&#xff1a;深度實戰 通過訓練一個智能體玩游戲 來洞察 強化學習&#xff08;RL&#xff09;與決策系統 在深度學習的廣闊領域中&#xff0c;強化學習&#xff08;Reinforcement Learning, RL&#xff09;是一種獨特的范式&#xff0c;它通過智能體與環境…