前言
前一篇介紹了如何將 NVIDIA Jetbot 原廠避障範例從雙類別改為多類別,由於篇幅關係只講到收集資料,本文接續把後續兩大步驟,也就是訓練模型與實際展示一口氣講完喔!來看看 CAVEDU YTshort 吧,歡迎按讚訂閱分享開啟小鈴鐺喔
CAVEDU 教育團隊針 對 Jetbot 已辦理過多次 Jetbot 道路識別競賽,有興趣的單位歡迎洽詢,我們可提供研習、師資訓練與比賽相關設備!
- [活動紀錄] 2022 RK-Jetbot機器學習道路識別競賽-彰化邀請賽@鹿港高中
- [活動紀錄] 2021 RK-Jetbot機器學習道路識別競賽-中區邀請賽@后綜高中
- [活動紀錄] 2020 RK-Jetbot機器學習道路辨別競賽@台北教育博覽會
本文
本文接續 [RK-JETBOT 避開障礙物功能多類別辨識教學 – 收集資料篇],介紹訓練模型與實際展示兩大階段,希望各位都能從中體驗機器人的魅力!
撰寫/攝影 | 郭俊廷 | ||
時間 | 2 小時 | 材料表 |
|
難度 | 3(滿分5) |
訓練模型
在畫面左側的畫面中,開啟 home > jetbot_CAVEDU/collision_avoidance/train_modelC3.ipynb
,這個檔案負責把前一個步驟所收集的資料集訓練成 pytorch 模型檔 (.pth)。
以下區塊是解壓縮資料集壓縮檔,如果不需要解壓縮的話可以跳過這一步驟。更改以下語法中的 dataset.zip
檔名來對應到您實際的檔案名稱。預設是註解掉程式無法執行,如要執行請取消註解即可。
第1個區塊設定訓練用資料集的資料夾名稱,更改底下的 class3
來對應實際名稱。
第2個區塊設定訓練後的模型檔名稱,請自由更改 ‘ ‘ 中內容來對應您要的模型檔名。第3個區塊設定訓練回合數預設是20回合,建議也訓練20回合以上。
執行第4個區塊,匯入PyTorch, NumPy, Python Imaging Library
等函式庫,在此無需修改,日後等您對於程式架構更佳掌握之後再回頭試試看吧!
第5、6個區塊設定功率模式以及開啟風扇,這裡的語法同樣不需要也不建議修改。設定功率模式為 5W
,是因為當訓練時Jetson Nano功率會使用到最大功率,如果使用MICRO USB供電時會因為輸出功率不足而斷電,如果改用 DC接頭供電就可以使用10W功率訓練。
第7個區塊會建立一個 dataset
實例,把 dataset 資料夾中的資料使用 torchvision.datasets 套件包與 torchvision.transforms數據包來分類跟轉換資料。
第8個區塊將資料集拆分為訓練集和測試集。
第9個區塊設定訓練集和測試集的參數
第10個區塊是定義神經網路,在此使用 alexnet 模型,初次使用會下載alexnet模型,實際下載時間根據您的網路速度而異,請耐心等候,並區塊前面顯示*號。(如果是使用 CAVEDU 所提供的映像檔,則都已經預先下載好囉!)
第11個區塊是將 alexnet 模型原本的1000個類別標籤輸出,改為3個。之所以為 3 是因為本範例共要辨識三個不同的障礙物,如果您希望辨識更多類別則請修改這個數字。
第12個區塊是將模型搬到在GPU上執行。
第13個區塊即開始將資料集訓練成模型檔,預設訓練20回合,根據建議各類別100張左右的照片訓練時間大約為十分鐘。訓練完成會產生一個一開始設定好名稱best_model3class.pth的模型檔(訓練完成後會如下圖所示顯示Done!)
最後一個區塊執行後會關閉風扇。
Live Demo 下場試車啦
這是一系列範例中的第三個 ipynb,也是最後一個,您的車子會使用先前所訓練好的 .pth 模型檔來執行視覺辨識任務。
在畫面左側的畫面中,開啟 home >jetbot_CAVEDU/collision_avoidance/live_demoC3.ipynb
,就能看到 Collision Avoidance – Live Demo 畫面。
這份程式負責執行訓練好的模型檔,也就是根據攝影機畫面進行推論為某個類別,並做出您所設定的動作。
請注意:在此需要有相對應的模型檔才可以執行該檔案,換言之,如果您已經有現成模型的話,就可以直接開車啦!實際跑車時,場地的背景跟燈光不能與收集資料集的狀況差異太多,否則視覺辨識的效果會不好喔。
第2個區塊使用 best_model_3class.pth
這個模型,請自行修改為您實際的檔名。
第2個區塊定義馬達參數,CAVEDU 目前採用 DFRobot 馬達驅動板所以不需要修改,如果您使用其他板子例如 waveshare 請自行修改。
執行後看到下圖 board begin success 代表馬達驅動板正常啟動,如果顯示失敗請檢查板子有無正確插上Jetson Nano上的GPIO以及正確接上電源。
第3、4個區塊設定功率模式以及開啟風扇,設定功率模式到 10W 可以提高系統效能。
第5個區塊是設定 PyTorch 的 alexnet 模型參數,請注意下圖數字 3 需對應先前所訓練模型的資料類別,如果您希望更多類別則記得要修改為對應的數字。
第6個區塊是載入模型檔,第7個區塊是把模型權重從 CPU 記憶體搬到 GPU 來執行。
第8個區塊是定義影像預處理方法,依序執行了以下內容
- 從BGR轉換為RGB模式
- 從HWC佈局轉換為CHW佈局
- 使用與訓練期間相同的參數進行正規化(攝影機像素範圍是[0,255],因此要 / 255 將其調整到範圍內的值,並在[0,1]範圍內訓練加載的圖像,因此我們需要縮放255.0
- 將資料從 CPU 搬到 GPU
- 針對批 (batch) 新增一個維度
第9個區塊建立一個大小為 224 * 224 的攝影機畫面,並針對每一個類別都有一個對應的滑桿,以視覺效果來呈現攝影機目前畫面所對應的類別機率 (機率值為 0~1 之間的小數),如下圖。
根據之前蒐集的資料分為a b c三個滑桿對應other blue red 三種類別的機率
a_slider = widgets.FloatSlider(description='other', min=0.0, max=1.0, orientation='vertical')
b_slider = widgets.FloatSlider(description='blue', min=0.0, max=1.0, orientation='vertical')
c_slider = widgets.FloatSlider(description='red', min=0.0, max=1.0, orientation='vertical')
並且在最後顯示出來的畫面也需要對應:
display(widgets.HBox([image, a_slider, b_slider, c_slider]))
第10個區塊,執行後機器人就會動了,請注意不要將JetBot放在桌上或是容易摔落撞到的地方(心疼)。修改程式碼說明如下:
首先在全域變數宣告,把新增的prob_a , prob_b, prob_c, a_slider, b_slider, c_slider變數跟滑桿都加上 global:
global robot, prob_a , prob_b, prob_c, a_slider, b_slider, c_slider
接著宣告 prob_a , prob_b, prob_c是對應系統陣列裡的哪個參數。float(y.flatten()[0])、float(y.flatten()[1])、float(y.flatten()[2])
排序是根據蒐集類別名稱的英文字母順序,如果是按照類別取名稱可能會造成排序錯亂,建議是按照英文字母順序取名。接著讓三個 slider.value 對應到各自的機率值。
prob_a = float(y.flatten()[0])
prob_b = float(y.flatten()[1])
prob_c = float(y.flatten()[2])
a_slider.value = prob_a
b_slider.value = prob_b
c_slider.value = prob_c
最後是修改程式碼將對應類別執行對應的動作,如下方程式會執行以下動作,您可以根據實際使用情境來修改機率門檻值與機器人動作:
- 當判斷類別a(other)的機率大於0.5的時候就以40%的速度前進
- 當判斷類別b(blue)的機率大於0.7就以70%的速度左轉
- 當判斷類別c(red)的機率大於0.7就以70%的速度右轉
if prob_a > 0.5:
robot.forward(0.4)
elif prob_b > 0.7:
robot.left(0.7)
elif prob_c > 0.7:
robot.right(0.7)
第11個區塊會更新攝影機畫面,如果沒有執行這一步驟,攝影機的畫面將無法同步,執行完這個區塊請往上拉回到第9個區塊來看看 JetBot 避障的效果如何。
第12個區塊,這裡會停止同步畫面,JetBot也會停止。第13個區塊是中斷攝影機的連結。
第14個區塊執行後會關閉風扇,風扇將會慢慢減速不會瞬間關閉請耐心等候。
總結
本文根據 JetBot 原廠教學,將原本的雙類別辨識擴充為多類別。機器人在製作過程有許多要注意的細節,幸好 NVIDIA Jetson 與 Jetbot 專案已經幫我們打通很多關節,期待您與我們分享您的機器人最新功能喔!