項(xiàng)目背景
我們正面臨著越來(lái)越多的嵌入機(jī)器學(xué)習(xí)革命。而當(dāng)我們談到機(jī)器學(xué)習(xí)(ML)時(shí),首先想到的就是圖像分類,一種 ML Hello World!
ESP32-CAM 是最受歡迎且價(jià)格合理的已集成攝像頭的開(kāi)發(fā)板之一,它結(jié)合了 Espressif ESP32-S MCU 芯片和 ArduCam OV2640 攝像頭。
ESP32 芯片功能強(qiáng)大,甚至可以處理圖像。它包括 I2C、SPI、UART 通信以及 PWM 和 DAC 輸出。
工作電壓:4.75-5.25V
飛濺:默認(rèn) 32Mbit
RAM:內(nèi)部 520KB + 外部 8MB PSRAM
無(wú)線網(wǎng)絡(luò):802.11b/g/n/e/i
藍(lán)牙:藍(lán)牙 4.2BR/EDR 和 BLE 標(biāo)準(zhǔn)
支持接口(2Mbps):UART、SPI、I2C、PWM
IO口:9
串口速率:默認(rèn)115200bps
頻譜范圍:2400 ~2483.5MHz
圖像輸出格式:JPEG(僅支持OV2640)、BMP、GRAYSCALE
下面,一般電路板引腳排列:
請(qǐng)注意,此設(shè)備沒(méi)有集成 USB-TTL 串行模塊,因此要將代碼上傳到 ESP32-CAM 需要一個(gè)特殊的適配器,如下所示:
或 USB-TTL 串行轉(zhuǎn)換適配器如下:
如果你想了解 ESP32-CAM,我強(qiáng)烈推薦Rui Santos 的書(shū)籍和教程。
在 Arduino IDE 上安裝 ESP32-Cam
從 Arduino IDE 打開(kāi)首選項(xiàng)窗口并轉(zhuǎn)到:Arduino 》偏好
使用以下行輸入:
https://dl.espressif.com/dl/package_esp32_index.json
在 Additional Board Manager URLs 中輸入下圖內(nèi)容
接著,打開(kāi) boards manager,轉(zhuǎn)到Tools 》 Board 》 Boards Manager.。。并使用esp32 輸入。選擇并安裝最新的軟件包
選擇 ESP32 開(kāi)發(fā)板:
例如,AI-Thinker ESP32-CAM
最后別忘記選擇連接 ESP32-Cam的端口。
這就對(duì)了!設(shè)備應(yīng)該沒(méi)問(wèn)題。讓我們做一些測(cè)試。
用 BLINK 測(cè)試電路板
ESP32-CAM 有一個(gè)與 GPIO33 連接的內(nèi)置 LED。因此,相應(yīng)地更改 Blink 草圖:
#define LED_BUILT_IN 33 void setup() { pinMode(LED_BUILT_IN, OUTPUT); // Set the pin as output } // Remember that the pin work with inverted logic // LOW to Turn on and HIGH to turn off void loop() { digitalWrite(LED_BUILT_IN, LOW); //Turn on delay (1000); //Wait 1 sec digitalWrite(LED_BUILT_IN, HIGH); //Turn off delay (1000); //Wait 1 sec } |
特別提醒,LED 位于電路板下方。
測(cè)試 WiFi
ESP32S 的聲音特性之一是其 WiFi 功能。所以,讓我們測(cè)試一下它的收音機(jī),掃描它周?chē)?wifi 網(wǎng)絡(luò)。你可以做到這一點(diǎn),運(yùn)行板附帶的代碼示例之一。
轉(zhuǎn)到 Arduino IDE 示例并查找WiFI ==> WiFIScan
在串行監(jiān)視器上,您應(yīng)該會(huì)看到設(shè)備范圍內(nèi)的 wifi 網(wǎng)絡(luò)(SSID 和 RSSI)。這是我在家里得到的:
測(cè)試相機(jī)
對(duì)于相機(jī)測(cè)試,您可以使用以下代碼:
示例 ==> ESP32 ==> 相機(jī) ==> CameraWebServer
只選擇合適的相機(jī):
#define CAMERA_MODEL_AI_THINKER |
并使用網(wǎng)絡(luò)憑據(jù)輸入:
const char* ssid = "*********"; const char* password = "*********"; |
在串行監(jiān)視器上,您將獲得正確的地址來(lái)運(yùn)行您可以控制攝像機(jī)的服務(wù)器:
這里我輸入的是:http: //172.16.42.26
運(yùn)行你的網(wǎng)絡(luò)服務(wù)器
到目前為止,我們可以測(cè)試所有 ESP32-Cam 硬件(MCU 和攝像頭)以及 wifi 連接。現(xiàn)在,讓我們運(yùn)行一個(gè)更簡(jiǎn)單的代碼來(lái)捕獲單個(gè)圖像并將其呈現(xiàn)在一個(gè)簡(jiǎn)單的網(wǎng)頁(yè)上。本代碼基于 Rui Santos 偉大的教程:ESP32-CAM Take Photo and Display in Web Server 開(kāi)發(fā)
從 GitHub 下載文件:ESP332_CAM_HTTP_Server_STA ,更改 wifi 憑據(jù)并運(yùn)行代碼。結(jié)果如下:
嘗試檢查代碼;更容易理解相機(jī)的工作原理。
水果與蔬菜 - 圖像分類
現(xiàn)在我們已經(jīng)運(yùn)行了嵌入式相機(jī),是時(shí)候嘗試圖像分類了。
我們應(yīng)該開(kāi)始訓(xùn)練模型并繼續(xù)在 ESP32-CAM 上進(jìn)行推理。我們需要找到大量的數(shù)據(jù)用于訓(xùn)練模型。
TinyML 是一組與嵌入式設(shè)備上的機(jī)器學(xué)習(xí)推理相關(guān)的技術(shù),由于限制(在這種情況下主要是內(nèi)存),我們應(yīng)該將分類限制為三到四個(gè)類別。我們將蘋(píng)果與香蕉和土豆區(qū)分開(kāi)來(lái)(您可以嘗試其他類別)。
因此,讓我們找到一個(gè)包含這些類別的圖像的特定數(shù)據(jù)集。Kaggle 是一個(gè)好的開(kāi)始:
https://www.kaggle.com/kritikseth/fruit-and-vegetable-image-recognition
該數(shù)據(jù)集包含以下食品的圖像:
水果-香蕉、蘋(píng)果、梨、葡萄、橙子、獼猴桃、西瓜、石榴、菠蘿、芒果。
蔬菜- 黃瓜、胡蘿卜、辣椒、洋蔥、土豆、檸檬、番茄、蘿卜、甜菜根、卷心菜、生菜、菠菜、大豆、花椰菜、甜椒、辣椒、蘿卜、玉米、甜玉米、紅薯、辣椒粉、墨西哥胡椒、姜、 大蒜、 豌豆、 茄子。
每個(gè)類別分為訓(xùn)練(100 張圖像)、測(cè)試(10 張圖像)和驗(yàn)證(10 張圖像)。
將數(shù)據(jù)集從 Kaggle 網(wǎng)站下載到您的計(jì)算機(jī)。
使用 Edge Impulse Studio 訓(xùn)練模型
我們將使用 Edge Impulse 進(jìn)行培訓(xùn),這是在邊緣設(shè)備上進(jìn)行機(jī)器學(xué)習(xí)的領(lǐng)先開(kāi)發(fā)平臺(tái)。
在 Edge Impulse 輸入您的帳戶憑據(jù)(或創(chuàng)建一個(gè)免費(fèi)帳戶)。接下來(lái),創(chuàng)建一個(gè)新項(xiàng)目:
數(shù)據(jù)采集
接下來(lái),在上傳數(shù)據(jù)部分,從您的計(jì)算機(jī)上傳所選類別的文件:
如果您以三類數(shù)據(jù)結(jié)束,閱讀培訓(xùn)會(huì)有所幫助
您還可以上傳額外的數(shù)據(jù)以進(jìn)行進(jìn)一步的模型測(cè)試或拆分訓(xùn)練數(shù)據(jù)。
沖動(dòng)設(shè)計(jì)
脈沖獲取原始數(shù)據(jù)(在本例中為圖像),提取特征(調(diào)整圖片大小),然后使用學(xué)習(xí)塊對(duì)新數(shù)據(jù)進(jìn)行分類。
如前所述,對(duì)圖像進(jìn)行分類是深度學(xué)習(xí)最常見(jiàn)的用途,但要完成這項(xiàng)任務(wù)需要使用大量數(shù)據(jù)。每個(gè)類別我們有大約 90 張圖片。這個(gè)數(shù)字夠嗎?一點(diǎn)也不!我們將需要數(shù)千張圖像來(lái)“教授或建模”以區(qū)分蘋(píng)果和香蕉。但是,我們可以通過(guò)使用數(shù)千張圖像重新訓(xùn)練先前訓(xùn)練的模型來(lái)解決這個(gè)問(wèn)題。我們將這種技術(shù)稱為“遷移學(xué)習(xí)”(TL)。
使用 TL,我們可以在我們的數(shù)據(jù)上微調(diào)預(yù)訓(xùn)練的圖像分類模型,即使在相對(duì)較小的圖像數(shù)據(jù)集(我們的案例)中也能達(dá)到良好的性能。
因此,從原始圖像開(kāi)始,我們將調(diào)整它們的大小(96x96)像素,然后將它們提供給我們的遷移學(xué)習(xí)塊:
預(yù)處理(特征生成)
除了調(diào)整圖像大小外,我們還應(yīng)該將它們更改為灰度,以保持實(shí)際的 RGB 顏色深度。這樣做,我們的每個(gè)數(shù)據(jù)樣本都將具有 9 維、216 個(gè)特征 (96x96x1)。保持RGB,這個(gè)尺寸會(huì)大三倍。使用灰度有助于減少推理所需的最終內(nèi)存量。
不要忘記“保存參數(shù)”。這將生成要在訓(xùn)練中使用的特征。
培訓(xùn)(遷移學(xué)習(xí)和數(shù)據(jù)增強(qiáng))
2007 年,Google 推出了MobileNetV1,這是一個(gè)通用計(jì)算機(jī)視覺(jué)神經(jīng)網(wǎng)絡(luò)系列,專為移動(dòng)設(shè)備而設(shè)計(jì),支持分類、檢測(cè)等。MobileNets 是小型、低延遲、低功耗的模型,參數(shù)化以滿足各種用例的資源限制。
盡管基本的 MobileNet 架構(gòu)已經(jīng)很小并且具有低延遲,但很多時(shí)候,特定用例或應(yīng)用程序可能需要模型更小更快。為了構(gòu)建這些更小且計(jì)算成本更低的模型,MobileNet 引入了一個(gè)非常簡(jiǎn)單的參數(shù)α (alpha),稱為寬度乘數(shù)。寬度乘數(shù) α 的作用是在每一層均勻地細(xì)化網(wǎng)絡(luò)。
Edge Impulse Studio 提供 MobileNet V1(96x96 圖像)和 V2(96x96 和 160x160 圖像),具有多個(gè)不同的α值(從 0.05 到 1.0)。例如,對(duì)于 V2、160x160 圖像和 α=1.0,您將獲得最高準(zhǔn)確度。當(dāng)然,有一個(gè)權(quán)衡。精度越高,運(yùn)行模型所需的內(nèi)存就越多(大約 1.3M RAM 和 2.6M ROM),這意味著更多的延遲。
在另一個(gè)極端,使用 MobileNet V1 和 α=0.10(大約 53.2K RAM 和 101K ROM)將獲得更小的占用空間。
為了在 ESP32-CAM 上運(yùn)行這個(gè)項(xiàng)目,我們應(yīng)該停留在可能性的較低端,保證推理的情況,但不能保證高精度。
與深度學(xué)習(xí)一起使用的另一項(xiàng)必要技術(shù)是數(shù)據(jù)增強(qiáng)。數(shù)據(jù)增強(qiáng)是一種可以幫助提高機(jī)器學(xué)習(xí)模型準(zhǔn)確性的方法。數(shù)據(jù)增強(qiáng)系統(tǒng)在訓(xùn)練過(guò)程中(如翻轉(zhuǎn)、裁剪或旋轉(zhuǎn)圖像)對(duì)訓(xùn)練數(shù)據(jù)進(jìn)行小的、隨機(jī)的更改。
在這里,您可以看到 Edge Impulse 如何對(duì)您的數(shù)據(jù)實(shí)施數(shù)據(jù)增強(qiáng)策略:
# Implements the data augmentation policy def augment_image(image, label): # Flips the image randomly image = tf.image.random_flip_left_right(image) # Increase the image size, then randomly crop it down to # the original dimensions resize_factor = random.uniform(1, 1.2) new_height = math.floor(resize_factor * INPUT_SHAPE[0]) new_width = math.floor(resize_factor * INPUT_SHAPE[1]) image = tf.image.resize_with_crop_or_pad(image, new_height, new_width) image = tf.image.random_crop(image, size=INPUT_SHAPE) # Vary the brightness of the image image = tf.image.random_brightness(image, max_delta=0.2) return image, label |
在訓(xùn)練期間暴露于這些變化可以幫助防止模型通過(guò)“記憶”訓(xùn)練數(shù)據(jù)中的表面線索而走捷徑,這意味著它可以更好地反映數(shù)據(jù)集中深層的潛在模式。
我們模型的最后一層將有 16 個(gè)神經(jīng)元,其中 10% 的 dropout 用于防止過(guò)擬合。這是訓(xùn)練輸出:
結(jié)果不是很好。該模型達(dá)到了大約 77% 的準(zhǔn)確率,但預(yù)計(jì)在推理期間使用的 RAM 內(nèi)存量非常小(大約 60 KB),這非常好。
部署
訓(xùn)練后的模型將部署為 .zip Arduino 庫(kù),用于特定的 ESP32-Cam 代碼。
打開(kāi)您的 Arduino IDE 并在Sketch 下,轉(zhuǎn)到Include Library并添加.ZIP Library。選擇您剛剛從 Edge Impulse Studio 下載的文件,就是這樣!
在Arduino IDE 的示例選項(xiàng)卡下,您應(yīng)該在項(xiàng)目名稱下找到一個(gè)草圖代碼。
打開(kāi)靜態(tài)緩沖區(qū)示例:
您可以看到,第一段代碼正是調(diào)用了一個(gè)庫(kù),該庫(kù)具有在您的設(shè)備上運(yùn)行推理所需的一切。
#include 《ESP32-CAM-Fruit-vs-Veggies_inferencing.h》
當(dāng)然,這是一個(gè)通用代碼(一個(gè)“模板”),它只獲取一個(gè)原始數(shù)據(jù)樣本(存儲(chǔ)在變量中:features = {} 并運(yùn)行分類器,進(jìn)行推理。結(jié)果顯示在串行監(jiān)視器上。
我們應(yīng)該做的是從相機(jī)中獲取樣本(圖像),對(duì)其進(jìn)行預(yù)處理(調(diào)整為 96x96,轉(zhuǎn)換為灰度并平整它。這將是我們模型的輸入張量。輸出張量將是一個(gè)包含三個(gè)值,顯示每個(gè)類的概率。
在網(wǎng)站上:https ://github.com/edgeimpulse/example-esp32-cam,Edge impulse 改編了可用于相機(jī)測(cè)試的代碼(示例 ==》 ESP32 ==》 相機(jī) ==》 CameraWebServer),包括必要的在 ESP32-CAM 上運(yùn)行推理。在 GitHub 上,下載代碼Basic-Image-Classification,包括您的項(xiàng)目庫(kù),選擇您的相機(jī)和您的 wifi 網(wǎng)絡(luò)憑據(jù):
將代碼上傳到您的 ESP32-Cam,您應(yīng)該可以開(kāi)始對(duì)水果和蔬菜進(jìn)行分類了!您可以在串行監(jiān)視器上檢查它:
測(cè)試模型(推理)
用相機(jī)拍照,分類結(jié)果會(huì)出現(xiàn)在串口監(jiān)視器上:
可以在網(wǎng)頁(yè)上驗(yàn)證相機(jī)捕獲的圖像:
其他測(cè)試:
結(jié)論
ESP32-Cam 是一種非常靈活、不昂貴且易于編程的設(shè)備。該項(xiàng)目可以證明 TinyML 的潛力,但我不確定整體結(jié)果是否可以應(yīng)用于實(shí)際應(yīng)用程序(以開(kāi)發(fā)的方式)。只有最小的遷移學(xué)習(xí)模型才能正常工作(MobileNet V1,α=0.10),任何使用更大的α來(lái)提高準(zhǔn)確性的嘗試都會(huì)導(dǎo)致 Arena 分配錯(cuò)誤。可能的原因之一是運(yùn)行相機(jī)的最終通用代碼中已經(jīng)使用的內(nèi)存量。因此,項(xiàng)目的下一步是優(yōu)化最終代碼,釋放更多內(nèi)存用于運(yùn)行模型。
-
攝像頭
+關(guān)注
關(guān)注
60文章
4849瀏覽量
95846 -
ESP32
+關(guān)注
關(guān)注
18文章
971瀏覽量
17353
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論