您對(duì)人工智能 (AI) 和機(jī)器學(xué)習(xí) (ML) 感到好奇嗎?您想知道如何在您已經(jīng)使用過(guò)的微控制器上使用它嗎?在本文中,我們向您介紹了微控制器上的機(jī)器學(xué)習(xí)。該主題也稱為微型機(jī)器學(xué)習(xí) (TinyML)。準(zhǔn)備好在石頭、紙、剪刀上輸給 ESP-EYE。您將了解數(shù)據(jù)收集和處理、如何設(shè)計(jì)和訓(xùn)練 AI 以及如何使其在 MCU 上運(yùn)行。這個(gè)示例為您提供了從頭到尾完成您自己的 TinyML 項(xiàng)目所需的一切。
我為什么要關(guān)心 TinyML?
您肯定聽說(shuō)過(guò) DeepMind 和 OpenAI 等科技公司。他們憑借專家和 GPU 能力在 ML 領(lǐng)域占據(jù)主導(dǎo)地位。為了給人一種規(guī)模感,最好的人工智能,比如谷歌翻譯使用的人工智能,需要幾個(gè)月的訓(xùn)練。他們并行使用數(shù)百個(gè)高性能 GPU。TinyML 通過(guò)變小來(lái)扭轉(zhuǎn)局面。由于內(nèi)存限制,大型 AI 模型不適合微控制器。下圖顯示了硬件要求之間的差異。
與在云端使用 AI 服務(wù)相比,MCU 上的機(jī)器學(xué)習(xí)有哪些優(yōu)勢(shì)?我們發(fā)現(xiàn)了七個(gè)主要優(yōu)勢(shì)。
成本
微控制器的購(gòu)買和運(yùn)行都很便宜。
環(huán)保
在微控制器上運(yùn)行 AI 消耗的能量很少。
一體化
微控制器很容易集成到現(xiàn)有環(huán)境中,例如生產(chǎn)線。
隱私和安全
數(shù)據(jù)可以在本地、在設(shè)備上處理。數(shù)據(jù)不必通過(guò)互聯(lián)網(wǎng)發(fā)送。
快速原型制作
TinyML 使您能夠在短時(shí)間內(nèi)開發(fā)概念驗(yàn)證解決方案。
自主可靠
即使沒有基礎(chǔ)設(shè)施,微型設(shè)備也可以在任何地方使用。
即時(shí)的
數(shù)據(jù)在微控制器上進(jìn)行處理,沒有延遲。唯一的限制是 MCU 的處理速度。
剪刀石頭布
你有沒有在石頭、紙、剪刀上輸給人工智能?或者你想通過(guò)擊敗人工智能來(lái)給你的朋友留下深刻印象?您將使用 TinyML 與 ESP-EYE 板對(duì)戰(zhàn)。要使這樣的項(xiàng)目成為可能,您需要學(xué)習(xí)五個(gè)步驟。以下部分提供了必要步驟的高級(jí)概述。如果您想仔細(xì)查看,請(qǐng)參閱我們項(xiàng)目存儲(chǔ)庫(kù)中的文檔。它解釋了漂亮的細(xì)節(jié)。
收集資料
收集數(shù)據(jù)是機(jī)器學(xué)習(xí)的關(guān)鍵部分。為了讓事情運(yùn)行起來(lái),你需要拍攝你的手形成石頭、紙、剪刀手勢(shì)的圖像。圖片越獨(dú)特越好。AI 將了解到您的手可以處于不同的角度、位置或光線變化。數(shù)據(jù)集包含記錄的圖像和每個(gè)圖像的標(biāo)簽。這被稱為監(jiān)督學(xué)習(xí)。
最好使用與訓(xùn)練 AI 相同的傳感器和環(huán)境來(lái)運(yùn)行您的 AI。這將確保模型熟悉傳入的數(shù)據(jù)。例如,考慮由于制造差異,溫度傳感器在相同溫度下具有不同的電壓輸出。就我們而言,這意味著使用 ESP-EYE 相機(jī)在統(tǒng)一的背景上記錄圖像是理想的選擇。在部署期間,人工智能將在類似的背景下工作得最好。您還可以使用網(wǎng)絡(luò)攝像頭記錄圖像,但可能會(huì)犧牲一些準(zhǔn)確性。由于 MCU 容量有限,我們記錄和處理 96×96 像素的灰度圖像。
收集數(shù)據(jù)后,將數(shù)據(jù)拆分為訓(xùn)練集和測(cè)試集非常重要。我們這樣做是為了看看我們的模型如何識(shí)別它以前從未見過(guò)的手勢(shì)圖像。該模型自然會(huì)在訓(xùn)練期間已經(jīng)看到的圖像上表現(xiàn)良好。
以下是一些示例圖像。如果您現(xiàn)在不想收集數(shù)據(jù),可以在這里下載我們現(xiàn)成的數(shù)據(jù)集。
預(yù)處理數(shù)據(jù)
識(shí)別數(shù)據(jù)中的模式不僅對(duì)人類來(lái)說(shuō)很困難。為了讓 AI 模型更容易做到這一點(diǎn),通常依賴于預(yù)處理算法。在我們的數(shù)據(jù)集中,我們使用 ESP-EYE 和網(wǎng)絡(luò)攝像頭記錄圖像。由于 ESP-EYE 可以捕獲 96×96 分辨率的灰度圖像,因此我們不需要在這里進(jìn)行太多進(jìn)一步的處理。但是,我們需要將網(wǎng)絡(luò)攝像頭圖像縮小并裁剪為 96×96 像素,并將它們從 RGB 轉(zhuǎn)換為灰度格式。最后,我們對(duì)所有圖像進(jìn)行歸一化。下面,您將看到我們處理的中間步驟。
設(shè)計(jì)模型
設(shè)計(jì)一個(gè)模型是相當(dāng)棘手的!詳細(xì)的處理超出了本文的范圍。我們將描述模型的基本組件以及我們?nèi)绾卧O(shè)計(jì)我們的模型。在引擎蓋下,我們的 AI 依賴于神經(jīng)網(wǎng)絡(luò)。您可以將神經(jīng)網(wǎng)絡(luò)視為神經(jīng)元的集合,有點(diǎn)像我們的大腦。這就是為什么在僵尸末日的情況下,人工智能也會(huì)被僵尸吃掉。
當(dāng)網(wǎng)絡(luò)中的所有神經(jīng)元相互連接時(shí),這稱為全連接或密集。這可以被認(rèn)為是最基本的神經(jīng)網(wǎng)絡(luò)類型。由于我們希望我們的 AI 能夠從圖像中識(shí)別手勢(shì),因此我們使用了一些更先進(jìn)且更適合圖像的東西,即卷積神經(jīng)網(wǎng)絡(luò) (CNN)。卷積降低了圖像的維度,提取了重要的模式并保留了像素之間的局部關(guān)系。為了設(shè)計(jì)一個(gè)模型,我們使用了TensorFlow 庫(kù),它提供了現(xiàn)成的神經(jīng)網(wǎng)絡(luò)組件,稱為層,這使得創(chuàng)建神經(jīng)網(wǎng)絡(luò)變得容易!
創(chuàng)建模型意味著堆疊層。它們的正確組合對(duì)于開發(fā)穩(wěn)健且高精度的模型至關(guān)重要。下圖顯示了我們正在使用的不同層。Conv2D表示卷積層。批標(biāo)準(zhǔn)化layer 對(duì)上一層的輸出應(yīng)用一種歸一化形式。然后我們將數(shù)據(jù)輸入激活層,這會(huì)引入非線性并過(guò)濾掉不重要的數(shù)據(jù)點(diǎn)。接下來(lái),最大池化類似于卷積減小圖像的大小。這個(gè)層塊重復(fù)了幾次;合適的量是由經(jīng)驗(yàn)和實(shí)驗(yàn)決定的。之后,我們使用扁平化層將二維圖像縮減為一維數(shù)組。最后,該陣列緊密連接到三個(gè)神經(jīng)元,它們分別代表石頭、紙和剪刀等類別。
def make_model_simple_cnn (INPUT_IMG_SHAPE, num_classes= 3 ): 輸入= keras.Input(形狀=INPUT_IMG_SHAPE) x = 輸入 x = layers.Rescaling( 1.0 / 255 )(x) x = layers.Conv2D( 16 , 3 , strides= 3 , padding= "same" )(x) x = layers.BatchNormalization()(x) x = layers.Activation( “relu” )(x) x = 層數(shù).MaxPooling2D()(x) x = layers.Conv2D( 32 , 3 , strides= 2 , padding= "same" , activation= "relu" )(x) x = 層數(shù).MaxPooling2D()(x) x = layers.Conv2D( 64 , 3 , padding= "same" , activation= "relu" )(x) x = 層數(shù).MaxPooling2D()(x) x = 層.Flatten()(x) x = 層數(shù).Dropout( 0.5 )(x) output = layers.Dense(units=num_classes, activation= "softmax" )(x) return keras.Model(inputs, outputs)
訓(xùn)練模型
一旦我們?cè)O(shè)計(jì)了一個(gè)模型,我們就可以訓(xùn)練它了。最初,人工智能模型會(huì)做出隨機(jī)預(yù)測(cè)。預(yù)測(cè)是與標(biāo)簽相關(guān)的概率,在我們的例子中是石頭、紙或剪刀。我們的 AI 告訴我們它將圖像視為每個(gè)標(biāo)簽的可能性有多大。因?yàn)槿斯ぶ悄茉谝婚_始就在猜測(cè)標(biāo)簽,所以它經(jīng)常會(huì)弄錯(cuò)標(biāo)簽。將預(yù)測(cè)標(biāo)簽與真實(shí)標(biāo)簽進(jìn)行比較后進(jìn)行訓(xùn)練。預(yù)測(cè)錯(cuò)誤會(huì)導(dǎo)致網(wǎng)絡(luò)中神經(jīng)元之間的更新。這種學(xué)習(xí)形式稱為梯度下降。因?yàn)槲覀冊(cè)?TensorFlow 中構(gòu)建了模型,所以訓(xùn)練就像一、二、三一樣簡(jiǎn)單。下面,您會(huì)看到訓(xùn)練期間產(chǎn)生的輸出——準(zhǔn)確度(訓(xùn)練集)和驗(yàn)證準(zhǔn)確度(測(cè)試集)越高越好!
時(shí)期1 / 6 480 / 480 [===============================] - 17秒34毫秒/步 - 損失:0.4738 - 準(zhǔn)確度:0.6579 - val_loss:0.3744 - val_accuracy:0.8718 Epoch 2 / 6 216 / 480 [============>....... ] - ETA:7秒 - 損失:0.2753 - 準(zhǔn)確度:0.8436
在訓(xùn)練期間,可能會(huì)出現(xiàn)多個(gè)問(wèn)題。最常見的問(wèn)題是過(guò)擬合。當(dāng)模型一遍又一遍地暴露在相同的例子中時(shí),它會(huì)開始記住訓(xùn)練數(shù)據(jù),而不是學(xué)習(xí)底層模式。當(dāng)然,您從學(xué)校記得理解比記憶更好!在某些時(shí)候,訓(xùn)練數(shù)據(jù)的準(zhǔn)確率可能會(huì)繼續(xù)上升,而測(cè)試集的準(zhǔn)確率則不會(huì)。這是過(guò)度擬合的明確指標(biāo)。
轉(zhuǎn)換模型
經(jīng)過(guò)訓(xùn)練,我們得到一個(gè) TensorFlow 格式的 AI 模型。由于 ESP-EYE 無(wú)法解釋這種格式,我們將模型更改為微處理器可讀格式。我們從轉(zhuǎn)換為 TfLite 模型開始。TfLite 是一種更緊湊的 TensorFlow 格式,它使用量化導(dǎo)致模型尺寸減小。TfLite 常用于世界各地的邊緣設(shè)備,例如智能手機(jī)或平板電腦。最后一步是將 TfLite 模型轉(zhuǎn)換為 C 數(shù)組,因?yàn)槲⒖刂破鳠o(wú)法直接解釋 TfLite。
部署模型
現(xiàn)在我們可以將模型部署到微處理器上。我們唯一需要做的就是將新的 C 數(shù)組放入預(yù)期的文件中。替換 C 數(shù)組的內(nèi)容,不要忘記替換文件末尾的數(shù)組長(zhǎng)度變量。我們提供了一個(gè)腳本來(lái)簡(jiǎn)化此操作。就是這樣!
嵌入式環(huán)境
讓我們回顧一下 MCU 上發(fā)生的事情。在設(shè)置過(guò)程中,解釋器被配置為我們圖像的形狀。
//初始化解釋器 靜態(tài)tflite::MicroInterpreter static_interpreter ( 模型、解析器、tensor_arena、kTensorArenaSize、error_reporter); 解釋器 = &static_interpreter; 模型輸入=解釋器->輸入(0); 模型輸出=解釋器->輸出(0); // 斷言真實(shí)輸入與期望輸入匹配 if ((model_input->dims->size != 4) || // 形狀 (1, 96, 96, 1) 的張量具有昏暗 4 (model_input->dims->data[ 0] != 1) || // 每批 1 個(gè) img (model_input->dims->data[1] != 96) || // 96 x 像素 (model_input->dims->data[2] != 96 ) || // 96 y 像素 (model_input->dims->data[3] != 1) || // 1 通道(灰度) (model_input->type != kTfLiteFloat32)) { // 單個(gè)數(shù)據(jù)的類型點(diǎn),這里是一個(gè)像素 error_reporter->Report( "Bad input tensor parameters in model\n" ); 返回; }
設(shè)置完成后,捕獲的圖像被發(fā)送到模型,在模型中進(jìn)行手勢(shì)預(yù)測(cè)。
// 從攝像頭讀取圖像到一維數(shù)組 uint8_t img[dim1*dim2*dim3] if (kTfLiteOk != GetImage(error_reporter, dim1, dim2, dim3, img)) { TF_LITE_REPORT_ERROR(error_reporter, "圖像捕獲失敗。" ); } // 將圖像寫入模型 std :: vector < uint8_t > img_vec(img, img + dim1*dim2*dim3); std ::向量< float_t > img_float(img_vec.begin(), img_vec.end()); 標(biāo)準(zhǔn)::copy(img_float.begin(), img_float.end(), model_input->data.f); // 應(yīng)用推理 TfLiteStatus invoke_status = 解釋器->Invoke(); }
然后模型返回每個(gè)手勢(shì)的概率。由于概率數(shù)組只是一系列介于 0 和 1 之間的值,因此需要進(jìn)行一些解釋。我們認(rèn)為識(shí)別出的手勢(shì)是概率最高的手勢(shì)。現(xiàn)在我們通過(guò)將識(shí)別的手勢(shì)與 AI 的動(dòng)作進(jìn)行比較來(lái)處理解釋,并確定誰(shuí)贏得了回合。你沒有機(jī)會(huì)了!
// 每個(gè)類的概率 浮動(dòng)紙=模型輸出->數(shù)據(jù).f[0]; 浮動(dòng)巖石 = model_output->data.f[1]; 浮動(dòng)剪刀 = model_output->data.f[2];
下面的可愛圖表說(shuō)明了 MCU 上的步驟。出于我們的目的,不需要對(duì)微控制器進(jìn)行預(yù)處理。
點(diǎn)擊查看完整大小的圖片
展開示例
來(lái)個(gè)挑戰(zhàn)怎么樣?人生的新目標(biāo)?想要給老朋友留下深刻印象或?qū)ふ倚屡笥眩客ㄟ^(guò)添加蜥蜴和史波克,將石頭、紙、剪刀提升到一個(gè)新的水平。你的 AI 朋友將是一項(xiàng)更接近世界統(tǒng)治的技能。好吧,首先你應(yīng)該看看我們的石頭、紙、剪刀存儲(chǔ)庫(kù),并能夠復(fù)制上述步驟。自述文件將幫助您了解詳細(xì)信息。下圖向您展示了游戲的運(yùn)作方式。您需要添加兩個(gè)額外的手勢(shì)和一些新的輸贏條件。
點(diǎn)擊查看完整大小的圖片
開始你自己的項(xiàng)目
如果您喜歡這篇文章并想開始自己的項(xiàng)目,我們會(huì)為您提供一個(gè)模板項(xiàng)目,它使用與我們的石頭、紙、剪刀項(xiàng)目相同的簡(jiǎn)單管道。您可以在此處找到模板。不要猶豫,通過(guò)社交媒體向我們展示您的項(xiàng)目。我們很想看看你能創(chuàng)造什么!
您可以在這里和那里找到有關(guān) TinyML 的更多信息。Pete Warden 的書是一個(gè)很好的資源。
審核編輯 黃昊宇
-
mcu
+關(guān)注
關(guān)注
146文章
17353瀏覽量
352783 -
AI
+關(guān)注
關(guān)注
87文章
31670瀏覽量
270472
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
利用TinyML在MCU上實(shí)現(xiàn)AI/ML推論工作
【先楫HPM5361EVK開發(fā)板試用體驗(yàn)】:4、TinyML測(cè)試(1)
如何在嵌入式系統(tǒng)或快速原型構(gòu)建板上實(shí)現(xiàn)即交即用式部署?
如何在esp8266 Node MCU的硬件上部署LVGL
什么是TinyML?微型機(jī)器學(xué)習(xí)
如何在AT32F系列MCU上使用FreeRTOS
如何在云平臺(tái)上實(shí)現(xiàn)應(yīng)用的快速部署?
如何在MCU上進(jìn)行實(shí)際的部署
MCU上的TinyML變速箱故障預(yù)測(cè)開源分享
![<b class='flag-5'>MCU</b><b class='flag-5'>上</b>的<b class='flag-5'>TinyML</b>變速箱故障預(yù)測(cè)開源分享](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
TinyML:ESP32 CAM和TFT上的實(shí)時(shí)圖像分類
![<b class='flag-5'>TinyML</b>:ESP32 CAM和TFT<b class='flag-5'>上</b>的實(shí)時(shí)圖像分類](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
如何在FTDI FT2232H上使用快速串行模式
![如<b class='flag-5'>何在</b>FTDI FT2232H<b class='flag-5'>上</b>使用<b class='flag-5'>快速</b>串行模式](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
如何在KV260上快速體驗(yàn)Vitsi AI圖像分類示例程序
![如<b class='flag-5'>何在</b>KV260<b class='flag-5'>上</b><b class='flag-5'>快速</b>體驗(yàn)Vitsi AI圖像分類示例程序](https://file1.elecfans.com/web2/M00/A2/91/wKgZomT_xzaANnPBAAAYl_pGrV4041.jpg)
如何在DRA821U上使用Linux實(shí)現(xiàn)快速引導(dǎo)
![如<b class='flag-5'>何在</b>DRA821U<b class='flag-5'>上</b>使用Linux實(shí)現(xiàn)<b class='flag-5'>快速</b>引導(dǎo)](https://file.elecfans.com/web1/M00/D9/4E/pIYBAF_1ac2Ac0EEAABDkS1IP1s689.png)
評(píng)論