資料介紹
描述
Dmitry Maslov 在 Seeed 工作室博客上的原創(chuàng)文章。
在今天的文章中,我們將使用用于微控制器的 Wio Terminal 和 Tensorflow Lite 創(chuàng)建一個智能氣象站,能夠根據(jù) BME280 環(huán)境傳感器的本地數(shù)據(jù)預(yù)測未來 24 小時的天氣和降水。
。
我將告訴你如何應(yīng)用模型優(yōu)化技術(shù),這不僅可以運行中型卷積神經(jīng)網(wǎng)絡(luò),還可以讓這個時尚的 GUI 和 WiFi 連接在同一時間同時運行數(shù)天和數(shù)月!
2022 年 3 月 29 日更新。我盡我所能定期更新我的文章,并根據(jù)您在 YouTube/Hackster 評論部分的反饋。如果您想表達對這些努力的支持和贊賞,請考慮給我買杯咖啡(或披薩):) 。
這是最終結(jié)果,您可以看到屏幕上顯示當(dāng)前溫度、濕度和大氣壓力值,以及城市名稱、預(yù)測天氣類型和預(yù)測降水機會——屏幕底部有一個日志輸出字段,您可以輕松地將其重新用于顯示極端天氣信息、人工智能笑話或來自我的推文。 雖然它看起來不錯且有用,但您可以自己添加很多東西 - 例如上面提到的屏幕上的新聞/推文輸出或使用深度睡眠模式來節(jié)省能源并使其由電池供電等等。
這個項目擴展了我的同事Jonathan Tan的一篇關(guān)于天氣預(yù)報的文章。最值得注意的是,我們將從該文章中的基本實現(xiàn)中改進一些內(nèi)容:
- 我們將使用 BME280 傳感器,它可以用來獲取大氣壓力信息,以及溫度和濕度。
- 原始項目中的神經(jīng)網(wǎng)絡(luò)模型經(jīng)過訓(xùn)練,可以根據(jù)前 3 小時的數(shù)據(jù)點預(yù)測下半小時的天氣,每半小時測量一次。所以,它更像是一個天氣描述符,而不是一個真正的天氣預(yù)報。我們將利用更先進的數(shù)據(jù)處理和模型架構(gòu),根據(jù)之前 24 小時的測量結(jié)果預(yù)測未來 24 小時的天氣類型和降水機會。
- 我們還將利用模型優(yōu)化,這將使我們能夠獲得更小的模型并在 Wio Terminal 內(nèi)存中容納更多的東西,例如,Web 服務(wù)器和帶有暗/亮材質(zhì)主題的漂亮 LVGL 界面。
數(shù)據(jù)處理和模型訓(xùn)練
那么,我們從哪里開始呢?當(dāng)然,這一切都始于數(shù)據(jù)。在本教程中,我們將使用來自 Kaggle 的現(xiàn)成天氣數(shù)據(jù)集,歷史每小時天氣數(shù)據(jù) 2012-2017。 我住在深圳,中國南方的一個城市——數(shù)據(jù)集中沒有那個城市,所以我選擇了一個緯度相近,也屬于亞熱帶氣候的城市——邁阿密。
你需要選擇一個至少與你居住的氣候相似的城市——不用說,這個模型在邁阿密的數(shù)據(jù)上進行了訓(xùn)練,然后在冬天部署到芝加哥,這將是 Confused Beyond All Reason。
對于數(shù)據(jù)處理和模型訓(xùn)練步驟,讓我們打開我為這個項目在 Github 存儲庫中準備和共享的 Colab Notebook 。
準備環(huán)境
獲得訓(xùn)練好的模型后,就可以將其部署到 Wio Terminal。
編輯 2021 年 10 月:如果您為 Wio 終端使用 1.8.2 板定義,則無需替換 cmsis_gcc.h。這也是 TC3 定時器庫正常運行所必需的。
其次,您需要將 cmsis_gcc.h 文件的內(nèi)容替換為較新的版本,以避免`__SXTB16_RORn`
未定義。您將在此項目的 Github 存儲庫中找到該文件的較新版本。然后只需將其復(fù)制到C:\Users\[your_user_name]\AppData\Local\Arduino15\packages\Seeeduino\tools\CMSIS\5.4.0\CMSIS\Core\Include
Windows 和/home/[your_user_name]/.arduino15/packages/Seeeduino/tools/CMSIS/5.4.0/CMSIS/Core/Include
Linux 上。
最后,由于我們使用卷積神經(jīng)網(wǎng)絡(luò)并使用 Keras API 構(gòu)建它,它包含當(dāng)前穩(wěn)定版本的 Tensorflow Micro 不支持的操作。瀏覽 Github 上的 Tensorflow 問題,我發(fā)現(xiàn)有一個拉取請求將此操作(EXPAND_DIMS)添加到可用操作列表中,但在撰寫本文時它沒有合并到 master 中。因此,您需要做的(2021 年 10 月編輯)是執(zhí)行
git clone https://github.com/tensorflow/tflite-micro-arduino-examples Arduino_TensorFlowLite
在您的 Arduino 草圖/庫文件夾中。您可以在TensorFlow Lite Micro Library for Arduino 存儲庫中找到有關(guān)安裝最新開發(fā)版本庫的更多詳細信息。
使用虛擬數(shù)據(jù)進行測試
完成后,創(chuàng)建一個空草圖并保存。然后將您訓(xùn)練的模型復(fù)制到草圖文件夾并重新打開草圖。將模型和模型長度的變量名稱更改為更短的名稱。然后使用 wio_terminal_tfmicro_weather_prediction_static.ino 中的代碼進行測試:
讓我們回顧一下我們在 C++ 代碼中的主要步驟
我們包含了 Tensorflow 庫的頭文件和帶有模型 flatbuffer 的文件
#include
//#include "tensorflow/lite/micro/micro_mutable_op_resolver.h"
#include "tensorflow/lite/micro/all_ops_resolver.h"
#include "tensorflow/lite/micro/micro_error_reporter.h"
#include "tensorflow/lite/micro/system_setup.h"
#include "tensorflow/lite/micro/micro_interpreter.h"
#include "tensorflow/lite/schema/schema_generated.h"
#include "model_Conv1D.h"
請注意我如何注釋掉 micro_mutable_op_resolver.h 并啟用 all_ops_resolver.h – all_ops_resolver.h 標頭編譯了 Tensorflow Micro 中當(dāng)前存在的所有操作并且便于測試,但是一旦完成測試,最好切換到 micro_mutable_op_resolver.h 以保存設(shè)備內(nèi)存——它確實有很大的不同。
接下來我們定義錯誤報告器、模型、輸入和輸出張量和解釋器的指針。注意我們的模型有兩個輸出——一個是降水量,另一個是天氣類型。我們還定義了 tensor arena,您可以將其視為一個草稿板,用于保存輸入、輸出和中間數(shù)組——所需的大小取決于您使用的模型,并且可能需要通過實驗來確定。
// Globals, used for compatibility with Arduino-style sketches.
namespace {
tflite::ErrorReporter* error_reporter = nullptr;
const tflite::Model* model = nullptr;
tflite::MicroInterpreter* interpreter = nullptr;
TfLiteTensor* input = nullptr;
TfLiteTensor* output_type = nullptr;
TfLiteTensor* output_precip = nullptr;
constexpr int kTensorArenaSize = 1024*25;
uint8_t tensor_arena[kTensorArenaSize];
} // namespace
然后在 setup 函數(shù)中,有更多樣板文件,例如實例化錯誤報告器、操作解析器、解釋器、映射模型、分配張量以及最后檢查分配后的張量形狀。如果當(dāng)前版本的 Tensorflow Micro 庫不支持某些模型操作,則代碼可能會在運行時拋出錯誤。如果您有不受支持的操作,您可以更改模型架構(gòu)或自己添加對操作員的支持,通常是從 Tensorflow Lite 移植它。
void setup() {
Serial.begin(115200);
while (!Serial) {delay(10);}
// Set up logging. Google style is to avoid globals or statics because of
// lifetime uncertainty, but since this has a trivial destructor it's okay.
// NOLINTNEXTLINE(runtime-global-variables)
static tflite::MicroErrorReporter micro_error_reporter;
error_reporter = μ_error_reporter;
// Map the model into a usable data structure. This doesn't involve any
// copying or parsing, it's a very lightweight operation.
model = tflite::GetModel(Conv1D_tflite);
if (model->version() != TFLITE_SCHEMA_VERSION) {
TF_LITE_REPORT_ERROR(error_reporter,
"Model provided is schema version %d not equal "
"to supported version %d.",
model->version(), TFLITE_SCHEMA_VERSION);
return;
}
// This pulls in all the operation implementations we need.
// NOLINTNEXTLINE(runtime-global-variables)
//static tflite::MicroMutableOpResolver<1> resolver;
static tflite::AllOpsResolver resolver;
// Build an interpreter to run the model with.
static tflite::MicroInterpreter static_interpreter(model, resolver, tensor_arena, kTensorArenaSize, error_reporter);
interpreter = &static_interpreter;
// Allocate memory from the tensor_arena for the model's tensors.
TfLiteStatus allocate_status = interpreter->AllocateTensors();
if (allocate_status != kTfLiteOk) {
TF_LITE_REPORT_ERROR(error_reporter, "AllocateTensors() failed");
return;
}
// Obtain pointers to the model's input and output tensors.
input = interpreter->input(0);
output_type = interpreter->output(1);
output_precip = interpreter->output(0);
Serial.println(input->dims->size);
Serial.println(input->dims->data[1]);
Serial.println(input->dims->data[2]);
Serial.println(input->type);
Serial.println(output_type->dims->size);
Serial.println(output_type->dims->data[1]);
Serial.println(output_type->type);
Serial.println(output_precip->dims->size);
Serial.println(output_precip->dims->data[1]);
Serial.println(output_precip->type);
}
最后,在循環(huán)函數(shù)中,我們?yōu)榱炕?INT8 值和浮點值數(shù)組定義了一個占位符,您可以從 Colab 筆記本復(fù)制粘貼,以比較設(shè)備上的模型推理與 Colab 中的模型推理。
void loop() {
int8_t x_quantized[72];
float x[72] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0};
我們在 for 循環(huán)中將浮點值量化為 INT8,并將它們一一放入輸入張量中:
for (byte i = 0; i < 72; i = i + 1) {
input->data.int8[i] = x[i] / input->params.scale + input->params.zero_point;
}
然后由 Tensorflow Micro 解釋器執(zhí)行推理,如果沒有報告錯誤,則將值放置在輸出張量中。
// Run inference, and report any error
TfLiteStatus invoke_status = interpreter->Invoke();
if (invoke_status != kTfLiteOk) {
TF_LITE_REPORT_ERROR(error_reporter, "Invoke failed");
return;
}
與輸入類似,模型的輸出也是量化的,所以我們需要進行逆運算,將其從INT8轉(zhuǎn)換為float。
// Obtain the quantized output from model's output tensor
float y_type[4];
// Dequantize the output from integer to floating-point
int8_t y_precip_q = output_precip->data.int8[0];
Serial.println(y_precip_q);
float y_precip = (y_precip_q - output_precip->params.zero_point) * output_precip->params.scale;
Serial.print("Precip: ");
Serial.print(y_precip);
Serial.print("\t");
Serial.print("Type: ");
for (byte i = 0; i < 4; i = i + 1) {
y_type[i] = (output_type->data.int8[i] - output_type->params.zero_point) * output_type->params.scale;
Serial.print(y_type[i]);
Serial.print(" ");
}
Serial.print("\n");
}
檢查并比較同一數(shù)據(jù)點的值,對于 Colab 筆記本中的量化 Tensorflow Lite 模型和在 Wio 終端上運行的 Tensorflow Micro 模型,它們應(yīng)該相同。
探索并嘗試完整版的草圖
涼爽的!所以它確實有效,現(xiàn)在下一步是將其從演示變成實際有用的項目。從 Seeed Arduino 速寫本存儲庫打開速寫并查看其內(nèi)容。
我將代碼分為主草圖、get_historical_data 和 GUI 部分。由于我們的模型需要過去 24 小時的數(shù)據(jù),我們需要等待 24 小時才能執(zhí)行第一次推理,這需要很多時間——為了解決這個問題,我們從 openweathermap.com API 獲取過去 24 小時的天氣,并且可以執(zhí)行第一次推理設(shè)備啟動后立即推斷,然后用連接到 Wio 終端 I2C Grove 插座的 BME280 傳感器的溫度、濕度和壓力替換循環(huán)緩沖區(qū)中的值。對于 GUI,我使用了 LVGL,一個小巧而多功能的圖形庫——它也是一個快速發(fā)展的項目,使用它并不容易,但它的功能非常值得!
按照 Github 存儲庫中的說明安裝必要的庫并配置 LVGL 以運行演示。
直到下一次!
- Arduino在線氣象站(NodeMCU)
- 如何制作簡單的氣象站
- Arduino無線氣象站
- Arduino氣象站
- 基于LoPy4的氣象站設(shè)計 0次下載
- Sigfox和Arduino氣象站
- 基于Arduino的無線氣象站 0次下載
- Arduino氣象站項目
- DIY簡單氣象站
- 使用Arduino和NodeMCU的氣象站
- 基于網(wǎng)絡(luò)的InqWeather氣象站
- 手持式氣象站BNL-GPRS系列使用手冊 4次下載
- 帶有Adafruit_IO的氣象站監(jiān)視器源碼 9次下載
- 自動氣象站的抗干擾技術(shù) 26次下載
- 基于MSP430的智能氣象站的設(shè)計
- 如何使用TensorFlow構(gòu)建機器學(xué)習(xí)模型 777次閱讀
- 4G氣象站的設(shè)計與實現(xiàn) 880次閱讀
- 如何在Vitis HLS中使用C語言代碼創(chuàng)建AXI4-Lite接口 1582次閱讀
- 如何利用ESP8266實現(xiàn)防雨物聯(lián)網(wǎng)氣象站的設(shè)計 4963次閱讀
- TensorFlow Lite實現(xiàn)移植到ART-Pi Smart 1927次閱讀
- 如何使用ESP32創(chuàng)建一個氣象站 3771次閱讀
- 基于樹莓派組成的可隨身攜帶氣象站設(shè)計方案 2815次閱讀
- 如何使用兩個dht傳感器及HC12模塊制作遠程氣象站? 2792次閱讀
- 基于創(chuàng)建帶有空氣質(zhì)量傳感器的室內(nèi)氣象站 2186次閱讀
- 如何在ESP32上使用代碼運行TensorFlow模型? 4526次閱讀
- 如何在Vitis HLS中使用C語言代碼創(chuàng)建AXI4-Lite接口 6248次閱讀
- dfrobotDIY智能氣象站套件簡介 1618次閱讀
- 如何利用Tensorflow搭建神經(jīng)網(wǎng)絡(luò)? 3000次閱讀
- TensorFlow Lite是TensorFlow針對移動和嵌入式設(shè)備的輕量級解決方案 2.5w次閱讀
- 基于STM32的自動氣象站控制模塊設(shè)計 8306次閱讀
下載排行
本周
- 1山景DSP芯片AP8248A2數(shù)據(jù)手冊
- 1.06 MB | 532次下載 | 免費
- 2RK3399完整板原理圖(支持平板,盒子VR)
- 3.28 MB | 339次下載 | 免費
- 3TC358743XBG評估板參考手冊
- 1.36 MB | 330次下載 | 免費
- 4DFM軟件使用教程
- 0.84 MB | 295次下載 | 免費
- 5元宇宙深度解析—未來的未來-風(fēng)口還是泡沫
- 6.40 MB | 227次下載 | 免費
- 6迪文DGUS開發(fā)指南
- 31.67 MB | 194次下載 | 免費
- 7元宇宙底層硬件系列報告
- 13.42 MB | 182次下載 | 免費
- 8FP5207XR-G1中文應(yīng)用手冊
- 1.09 MB | 178次下載 | 免費
本月
- 1OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 2555集成電路應(yīng)用800例(新編版)
- 0.00 MB | 33566次下載 | 免費
- 3接口電路圖大全
- 未知 | 30323次下載 | 免費
- 4開關(guān)電源設(shè)計實例指南
- 未知 | 21549次下載 | 免費
- 5電氣工程師手冊免費下載(新編第二版pdf電子書)
- 0.00 MB | 15349次下載 | 免費
- 6數(shù)字電路基礎(chǔ)pdf(下載)
- 未知 | 13750次下載 | 免費
- 7電子制作實例集錦 下載
- 未知 | 8113次下載 | 免費
- 8《LED驅(qū)動電路設(shè)計》 溫德爾著
- 0.00 MB | 6656次下載 | 免費
總榜
- 1matlab軟件下載入口
- 未知 | 935054次下載 | 免費
- 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
- 78.1 MB | 537798次下載 | 免費
- 3MATLAB 7.1 下載 (含軟件介紹)
- 未知 | 420027次下載 | 免費
- 4OrCAD10.5下載OrCAD10.5中文版軟件
- 0.00 MB | 234315次下載 | 免費
- 5Altium DXP2002下載入口
- 未知 | 233046次下載 | 免費
- 6電路仿真軟件multisim 10.0免費下載
- 340992 | 191187次下載 | 免費
- 7十天學(xué)會AVR單片機與C語言視頻教程 下載
- 158M | 183279次下載 | 免費
- 8proe5.0野火版下載(中文版免費下載)
- 未知 | 138040次下載 | 免費
評論
查看更多