本文介紹如何利用 Jetson Nano 結合機器學習技術,在物聯網環境下實作物件分類別與模式識別。透過 ESP32-CAM 捕捉影像並以 MQTT 協定傳輸至 Jetson Nano,利用預先訓練好的 SVM 與 KNN 模型進行影像辨識,最後將辨識結果透過 WhatsApp 通知使用者。程式碼涵蓋了資料準備、模型訓練、影像預處理、預測與通知等關鍵步驟,並以三角形、四邊形以及電子開發板等物件作為範例,展現了機器學習在物聯網應用中的實用性。
物件分類別與模式識別在物聯網中的應用
模式識別使用機器學習與雲端技術
在物聯網(IoT)應用中,模式識別是一項關鍵技術,尤其是在結合機器學習(ML)與雲端運算時。本章節將介紹如何利用Jetson Nano和機器學習技術來進行模式識別,包括三角形和四邊形的識別。
步驟1:資料準備
首先,需要準備用於訓練的資料集。將三角形和四邊形的影像分別儲存在不同的資料夾中,例如Triangle和Quadrilateral。
步驟2:模型訓練
使用支援向量機(SVM)演算法來訓練模型。以下是一個簡單的Python程式碼範例,展示如何進行模型訓練:
# model.py
import os
import numpy as np
import cv2
import pickle
from sklearn.model_selection import train_test_split
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score
# 資料準備
file = '/home/jetson/Desktop/Project/Pattern_recog'
categories = ['Quadrilateral', 'Triangle']
data = []
for category in categories:
path = os.path.join(file, category)
label = categories.index(category)
for img in os.listdir(path):
image_path = os.path.join(path, img)
image_shape = cv2.imread(image_path, 0)
try:
image_shape = cv2.resize(image_shape, (100, 100))
image = np.array(image_shape).flatten()
data.append([image, label])
except Exception as e:
pass
# 分割資料集
features = [d[0] for d in data]
labels = [d[1] for d in data]
X_train, X_test, Y_train, Y_test = train_test_split(features, labels, test_size=0.20)
# 訓練模型
model = SVC(C=1, kernel='poly', gamma='auto', degree=4, coef0=1.5)
model.fit(X_train, Y_train)
# 預測與評估
Y_pred = model.predict(X_test)
accuracy = accuracy_score(Y_test, Y_pred)
print('模型的準確度:', accuracy)
# 儲存模型
pick = open('model.sav', 'wb')
pickle.dump(model, pick)
pick.close()
#### 內容解密:
此程式碼首先匯入必要的函式庫,然後準備資料集。資料集包含三角形和四邊形的影像,分別儲存在不同的資料夾中。程式碼將這些影像讀取、縮放至100x100畫素,並扁平化為一維陣列。接著,使用SVM演算法訓練模型,並評估其準確度。最後,將訓練好的模型儲存為model.sav檔案。
步驟3:測試與識別
使用訓練好的模型來識別新的影像。以下是一個簡單的Python程式碼範例,展示如何進行測試與識別:
# main.py
import os
import numpy as np
import cv2
import pickle
from twilio.rest import Client
# 載入模型
pick = open('model.sav', 'rb')
model = pickle.load(pick)
# 識別測試影像
test_path = '/home/jetson/Desktop/Project/Pattern_recog/Test'
for img in os.listdir(test_path):
img_path = os.path.join(test_path, img)
image_shape = cv2.imread(img_path, 0)
image_shape = cv2.resize(image_shape, (100, 100))
image = np.array(image_shape).flatten()
image = image.reshape(1, -1)
result = model.predict(image)
# 傳送識別結果到WhatsApp
client = Client('your_account_sid', 'your_auth_token')
if result == [0]:
print('預測結果:四邊形')
message = client.messages.create(body='預測結果:四邊形', from_='whatsapp:+14155238886', to='whatsapp:+917057504996')
elif result == [1]:
print('預測結果:三角形')
message = client.messages.create(body='預測結果:三角形', from_='whatsapp:+14155238886', to='whatsapp:+91XXXXXXXXXX')
print(message.sid)
#### 內容解密:
此程式碼首先載入之前訓練好的SVM模型。然後,讀取測試影像,縮放並扁平化後,使用模型進行預測。根據預測結果,將識別結果傳送到指定的WhatsApp號碼。
物件分類別使用機器學習與霧運算
物件分類別是另一項重要的應用,尤其是在物聯網裝置中。本章節將介紹如何利用KNN演算法和霧運算來進行物件分類別。
概念圖
此係統的概念圖如圖6.9所示。Jetson Nano被組態為霧節點,而ESP32-CAM則作為IoT節點。霧節點接收由ESP32-CAM模組透過MQTT協定捕捉的測試影像,並將其儲存到Jetson Nano上的Test目錄中。KNN模型對來自Test目錄的影像進行預測,並透過Twilio雲將結果傳送到WhatsApp。
#### 圖表翻譯:
圖6.9展示了物件分類別系統的概念圖,包括霧節點(Jetson Nano)和IoT節點(ESP32-CAM)之間的互動。霧節點負責處理來自IoT節點的影像,並使用KNN模型進行物件分類別。
物件分類別系統在物聯網中的應用:以Jetson Nano為例
系統概述
本系統結合了物聯網(IoT)技術與機器學習(ML),利用Jetson Nano作為霧計算(FoG)節點,實作對物體的即時影像分類別。系統主要由兩個部分組成:ESP32-CAM作為IoT節點負責影像捕捉與傳輸,以及Jetson Nano負責影像接收、分類別和結果通知。
系統架構
硬體需求
- ESP32-CAM模組
- Jetson Nano開發板
- 網路連線裝置
軟體需求
- MicroPython(用於ESP32-CAM)
- Python 3(用於Jetson Nano)
- MQTT協定
- Twilio服務(用於WhatsApp通知)
ESP32-CAM端程式碼(main.py)
from machine import Pin
from umqtt.simple import MQTTClient
import time
import camera
import network
# 連線Wi-Fi
station = network.WLAN(network.STA_IF)
station.active(True)
station.connect("jetson-desktop", "11111111")
# MQTT伺服器設定
SERVER = '10.42.0.1'
CLIENT_ID = 'esp32-camera'
TOPIC = b'Image'
# 連線MQTT伺服器
c = MQTTClient(CLIENT_ID, SERVER)
c.connect()
# 初始化相機並捕捉影像
camera.init(0, format=camera.JPEG)
buf = camera.capture()
# 發布影像至MQTT主題
c.publish(TOPIC, buf)
time.sleep_ms(100)
內容解密:
- Wi-Fi連線設定:ESP32-CAM連線到Jetson Nano所建立的Wi-Fi熱點。
- MQTT客戶端初始化:使用
umqtt.simple函式庫建立MQTT客戶端,連線到Jetson Nano上的MQTT伺服器。 - 影像捕捉與發布:初始化相機,捕捉JPEG格式影像,並透過MQTT協定發布到指定主題。
Jetson Nano端設定與程式碼
Step 1-2:建立專案目錄與設定MQTT、Twilio服務
在Jetson Nano上建立專案目錄Object_classify,並在其中建立子目錄Test、Raspberry_pi、Jetson_nano、Py_board。組態Twilio和MQTT服務。
Step 3:訓練模型(model.py)
import os
import numpy as np
import cv2
import pickle
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
# 資料準備
file = '/home/jetson/Desktop/Project/Object_classify'
categories = ['Py_board', 'Raspberry_pi', 'Jetson_nano']
data = []
for category in categories:
path = os.path.join(file, category)
label = categories.index(category)
for img in os.listdir(path):
image_path = os.path.join(path, img)
image_shape = cv2.imread(image_path, 0)
try:
image_shape = cv2.resize(image_shape, (100, 100))
image = np.array(image_shape).flatten()
data.append([image, label])
except Exception as e:
pass
# 分割資料集與訓練模型
features = [d[0] for d in data]
labels = [d[1] for d in data]
X_train, X_test, Y_train, Y_test = train_test_split(features, labels, test_size=0.20)
model = KNeighborsClassifier(n_neighbors=3)
model.fit(X_train, Y_train)
# 儲存訓練好的模型
pick = open('model_obj.sav', 'wb')
pickle.dump(model, pick)
pick.close()
內容解密:
- 資料載入與預處理:從指定目錄載入影像資料,將其縮放至100x100畫素並扁平化處理。
- 模型訓練:使用KNN演算法訓練模型,並將訓練好的模型儲存為
.sav檔案。
Step 4:執行影像分類別(main.py)
import os
import numpy as np
import cv2
import pickle
from twilio.rest import Client
import paho.mqtt.client as mqtt
def predict():
# 載入測試影像並進行分類別
path = '/home/jetson/Desktop/Project/Object_classify/Test'
for img in os.listdir(path):
img_path = os.path.join(path, img)
image_shape = cv2.imread(img_path, 0)
image_shape = cv2.resize(image_shape, (100, 100))
image = np.array(image_shape).flatten()
image = image.reshape(1, -1)
# 載入模型並進行預測
pick = open('model_obj.sav', 'rb')
model = pickle.load(pick)
result = model.predict(image)
# 傳送預測結果至WhatsApp
t_client = Client('your_account_sid', 'your_auth_token')
if result == [0]:
t_message = t_client.messages.create(body='Prediction is Py Board',
from_='whatsapp:+14155238886',
to='whatsapp:+91XXXXXXXXXX')
elif result == [1]:
t_message = t_client.messages.create(body='Prediction is Raspberry Pi',
from_='whatsapp:+14155238886',
to='whatsapp:+91XXXXXXXXXX')
elif result == [2]:
t_message = t_client.messages.create(body='Prediction is Jetson Nano',
from_='whatsapp:+14155238886',
to='whatsapp:+91XXXXXXXXXX')
print("message sent")
# MQTT接收影像並儲存至Test目錄(省略部分程式碼)
內容解密:
- 影像分類別:載入測試影像,進行預處理後使用訓練好的KNN模型進行分類別。
- 結果通知:透過Twilio服務將分類別結果傳送至指定WhatsApp號碼。
6.5 利用邊緣運算的機器學習預測未知葡萄糖濃度
在維持生命的過程中,定期監測身體引數至關重要,這有助於避免因各種疾病(如糖尿病、心血管疾病等)引起的嚴重併發症。糖尿病是一種嚴重的疾病,其特徵是血糖水平升高。如果這種情況持續很長時間,將導致諸如腎衰竭、中風、截肢、心臟病發作、失明等健康問題。因此,對於糖尿病患者來說,定期監測血糖水平至關重要。目前市場上有葡萄糖監測儀器,但需要刺破手指取血。由於涉及刺痛,可能會引起疼痛並導致感染。為瞭解決這個問題,需要一種非侵入性的方法,例如利用人體組織的光學吸收特徵,目前在這一領域正在進行大量研究。在這個應用中,Jetson Nano單板電腦(SBC)作為邊緣節點,佈署了多層感知器(MLP)模型,以準確預測葡萄糖濃度。
邊緣運算簡介
邊緣運算是一種分散式框架,將客戶端的資料盡可能地在網路邊緣進行處理,即資料來源附近。為了考慮從人體血液樣本中預測的資料集,需要倫理許可。因此,我們使用了實驗室樣本而不是人體組織。樣本是透過混合五種主要的血液成分(葡萄糖、抗壞血酸、丙氨酸、乳酸和尿素)以生理相關的濃度在正常範圍內製備的。作者使用分光光度計Jasco V770建立了57個樣本的資料函式庫,這些樣本在三個波長(2246 nm、2280 nm和2308 nm)下具有吸收特徵。
MLP模型佈署與訓練
佈署在邊緣的MLP模型使用45個樣本進行訓練,並使用12個樣本進行驗證,即資料函式庫分割比例為80:20。MLP模型使用’RELU’啟用函式,最大迭代次數為30,000,並使用MinMaxScaler()歸一化函式進行資料標準化。葡萄糖預測的決定係數(R2)為0.99。
在Jetson Nano上實作葡萄糖預測的步驟
本文涵蓋了在Jetson Nano SBC平台上使用MLP演算法進行葡萄糖預測的實作步驟。
步驟1:更新和升級平台
以root使用者身份使用以下命令更新和升級平台:
sudo apt-get update
sudo apt-get upgrade
步驟2:安裝必要的函式庫/倉函式庫
透過在Jetson終端中指定的命令安裝以下函式庫:
sudo apt install python3-pip
sudo pip install -U scikit-learn
sudo pip install pickle-mixin
sudo pip3 install pandas
步驟3:建立專案目錄
在您所需的位置建立一個名為“Project”的目錄(作者選擇了桌面)。開啟“Project”目錄並建立一個名為“Glucose_pred”的子目錄。該目錄將儲存上述應用程式的資料集、訓練模型和程式。
步驟4:導航到“Glucose_pred”目錄
步驟5:儲存以下程式碼為“model.py”在“Glucose_pred”目錄中
# MLP迴歸器程式碼,用於在邊緣預測葡萄糖濃度
from sklearn.neural_network import MLPRegressor
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import MinMaxScaler
from sklearn.metrics import r2_score
import pandas as pd
import numpy as np
"""初始化資料集"""
x_train = np.array([[0.003509, 0.004917, 0.004881],
[0.003682, 0.004913, 0.005101],
[0.002919, 0.004060, 0.003594],
# ... 其他資料 ...
[0.003205, 0.004398, 0.004001],
[0.002653, 0.003393, 0.003574]])
#### 內容解密:
這段程式碼首先匯入必要的函式庫,包括`sklearn.neural_network`中的`MLPRegressor`、`sklearn.model_selection`中的`train_test_split`、`sklearn.preprocessing`中的`MinMaxScaler`以及`sklearn.metrics`中的`r2_score`。接著,它匯入了`pandas`和`numpy`函式庫,用於資料處理和數值計算。
程式碼中的`x_train`變數是一個numpy陣列,包含了用於訓練MLP模型的資料集。每行代表一個樣本,每列代表一個特徵(在三個不同的波長下的吸收值)。
### 葡萄糖預測流程圖
此圖示展示了葡萄糖預測的流程,包括資料準備、模型訓練和預測等步驟。
**圖表翻譯:**
此圖展示了利用MLP模型進行葡萄糖濃度預測的完整流程。首先,透過實驗室樣本製備和資料收集,建立了一個包含57個樣本的資料函式庫。然後,將資料分割為訓練集和測試集,分別用於模型的訓練和驗證。接著,利用MLPRegressor進行模型訓練,並使用MinMaxScaler進行資料標準化。最後,透過評估模型的R2得分來驗證其準確性。
### MQTT客戶端程式碼實作
```python
def on_connect(client, userdata, flags, rc):
print('連線成功,結果程式碼:{0}'.format(rc))
# 訂閱主題
client.subscribe('glucose')
def on_message(client, userdata, msg):
print(msg)
print("收到訊息-> " + msg.topic + " " + str(msg.payload))
f = open('test/' + 'Test_image.jpg', "wb")
f.write(msg.payload)
f.close()
print("影像已接收並儲存!")
predict()
client = mqtt.Client()
client.on_connect = on_connect # 指定連接回呼
client.on_message = on_message # 指定訊息回撥
client.connect('localhost', 1883, 60) # 連線到MQTT代理
client.loop_forever()
內容解密:
這段程式碼實作了一個MQTT客戶端,用於訂閱特定主題並接收訊息。當客戶端連線到MQTT代理時,會觸發on_connect回撥函式,並訂閱’glucose’主題。當收到訊息時,會觸發on_message回撥函式,將訊息儲存為影像檔案,並呼叫predict()函式進行葡萄糖濃度預測。
機器學習於物聯網中的應用:以 Jetson Nano 為例
機器學習模型在葡萄糖濃度預測中的應用
在物聯網(IoT)與機器學習(ML)的結閤中,Jetson Nano 提供了一個強大的平台來實作各種應用。本篇文章將重點介紹如何使用機器學習技術在 Jetson Nano 上進行葡萄糖濃度的預測。
步驟一:資料準備與預處理
首先,我們需要準備訓練資料集。資料集包含了不同波長下的葡萄糖濃度測量值。以下是範例資料:
import numpy as np
from sklearn.preprocessing import MinMaxScaler
from sklearn.neural_network import MLPRegressor
from sklearn.metrics import r2_score
# 訓練資料
x_train = np.array([[0.003611, 0.004533, 0.004147],
[0.002930, 0.004209, 0.004432],
[0.002984, 0.004320, 0.004504],
[0.002600, 0.003282, 0.003502],
[0.002367, 0.003055, 0.003166],
[0.002859, 0.003828, 0.003478],
[0.002686, 0.003510, 0.003634]])
y_train = np.array([[280], [70], [280], [200], [70], [70], [100]])
# 測試資料
x_test = np.array([[0.002276, 0.002680, 0.002201],
[0.002063, 0.002536, 0.002286],
[0.003644, 0.004650, 0.004207]])
y_test = np.array([[200], [100], [280]])
# 使用 Min-Max Scaler 進行資料標準化
scaler = MinMaxScaler()
scaler.fit(x_train)
x_train1 = scaler.transform(x_train)
x_test1 = scaler.transform(x_test)
#### 內容解密:
此步驟中,我們首先匯入必要的函式庫,並準備了訓練資料 x_train 和 y_train,以及測試資料 x_test 和 y_test。資料標準化是使用 MinMaxScaler 將資料縮放到相同的範圍內,以提高模型的訓練效率和準確性。
步驟二:建立與訓練機器學習模型
接下來,我們使用多層感知器迴歸器(MLPRegressor)建立機器學習模型,並對其進行訓練。
# 建立 MLPRegressor 模型
model = MLPRegressor(hidden_layer_sizes=(11, 8), activation="relu", random_state=1, max_iter=30000)
model.fit(x_train1, y_train)
# 使用模型進行預測
y_pred = model.predict(x_test1)
print("模型的 R2 分數:", r2_score(y_test, y_pred))
#### 內容解密:
在此步驟中,我們建立了一個具有兩個隱藏層的多層感知器迴歸模型,並使用訓練資料對其進行訓練。activation="relu" 表示使用 ReLU 啟用函式。模型訓練完成後,我們使用測試資料進行預測,並計算模型的 R2 分數以評估其效能。
步驟三:預測未知葡萄糖濃度
最後,我們可以使用訓練好的模型來預測未知葡萄糖濃度。
# 輸入待測樣本的波長值
W1 = float(input("輸入葡萄糖第一波長值:"))
W2 = float(input("輸入葡萄糖第二波長值:"))
W3 = float(input("輸入葡萄糖第三波長值:"))
wave_values = np.array([[W1, W2, W3]])
wave_values = scaler.transform(wave_values)
predicted = model.predict(wave_values)
print("預測的葡萄糖濃度是:", predicted)
#### 內容解密:
此步驟中,我們輸入待測樣本的三個波長值,使用訓練好的模型進行預測。首先,我們將輸入的波長值標準化,然後使用模型進行預測,最後輸出預測的葡萄糖濃度。
練習與擴充套件
- 改變影像解析度:參考第 6.3 節的範例,嘗試使用不同解析度的影像(如 200x200、150x150 和 50x50)來訓練模型,並觀察預測準確度的變化。
- 增加形狀類別:在第 6.3 節的活動中,嘗試增加資料集中的形狀類別(如四邊形、三角形和圓形/橢圓形),並將結果傳送到 Twilio 雲端。
- 替換 FoG 節點:在第 6.4 節中,探索使用 Raspberry Pi 替換 Jetson Nano 的可能性。
- 建立自有資料集:在第 6.4 節中,嘗試建立自己的資料集,並評估不同機器學習模型的效能。
- 引數調優:研究改變引數(如 C、degree 和 coefficient)對第 6.3 節系統準確度的影響,並評估使用 KNN 分類別器的準確度。
- 葡萄糖預測模型驗證:使用自建的葡萄糖感測器資料集來驗證葡萄糖預測模型的準確度。
透過這些練習和擴充套件,您可以更深入地理解機器學習在物聯網中的應用,並進一步提升相關技術的能力。