返回文章列表

物聯網物件分類別與模式識別應用

本文探討在物聯網中應用機器學習技術進行物件分類別與模式識別,以 Jetson Nano 作為邊緣計算平台,結合 ESP32-CAM 進行影像擷取和傳輸,並使用 MQTT 協定進行資料交換。文章涵蓋了使用 SVM 和 KNN 演算法訓練模型、影像預處理、結果預測與 WhatsApp 通知等環節,並提供了 Python

物聯網 機器學習

本文介紹如何利用 Jetson Nano 結合機器學習技術,在物聯網環境下實作物件分類別與模式識別。透過 ESP32-CAM 捕捉影像並以 MQTT 協定傳輸至 Jetson Nano,利用預先訓練好的 SVM 與 KNN 模型進行影像辨識,最後將辨識結果透過 WhatsApp 通知使用者。程式碼涵蓋了資料準備、模型訓練、影像預處理、預測與通知等關鍵步驟,並以三角形、四邊形以及電子開發板等物件作為範例,展現了機器學習在物聯網應用中的實用性。

物件分類別與模式識別在物聯網中的應用

模式識別使用機器學習與雲端技術

在物聯網(IoT)應用中,模式識別是一項關鍵技術,尤其是在結合機器學習(ML)與雲端運算時。本章節將介紹如何利用Jetson Nano和機器學習技術來進行模式識別,包括三角形和四邊形的識別。

步驟1:資料準備

首先,需要準備用於訓練的資料集。將三角形和四邊形的影像分別儲存在不同的資料夾中,例如TriangleQuadrilateral

步驟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)

內容解密:

  1. Wi-Fi連線設定:ESP32-CAM連線到Jetson Nano所建立的Wi-Fi熱點。
  2. MQTT客戶端初始化:使用umqtt.simple函式庫建立MQTT客戶端,連線到Jetson Nano上的MQTT伺服器。
  3. 影像捕捉與發布:初始化相機,捕捉JPEG格式影像,並透過MQTT協定發布到指定主題。

Jetson Nano端設定與程式碼

Step 1-2:建立專案目錄與設定MQTT、Twilio服務

在Jetson Nano上建立專案目錄Object_classify,並在其中建立子目錄TestRaspberry_piJetson_nanoPy_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()

內容解密:

  1. 資料載入與預處理:從指定目錄載入影像資料,將其縮放至100x100畫素並扁平化處理。
  2. 模型訓練:使用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目錄(省略部分程式碼)

內容解密:

  1. 影像分類別:載入測試影像,進行預處理後使用訓練好的KNN模型進行分類別。
  2. 結果通知:透過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_trainy_train,以及測試資料 x_testy_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)

#### 內容解密:

此步驟中,我們輸入待測樣本的三個波長值,使用訓練好的模型進行預測。首先,我們將輸入的波長值標準化,然後使用模型進行預測,最後輸出預測的葡萄糖濃度。

練習與擴充套件

  1. 改變影像解析度:參考第 6.3 節的範例,嘗試使用不同解析度的影像(如 200x200、150x150 和 50x50)來訓練模型,並觀察預測準確度的變化。
  2. 增加形狀類別:在第 6.3 節的活動中,嘗試增加資料集中的形狀類別(如四邊形、三角形和圓形/橢圓形),並將結果傳送到 Twilio 雲端。
  3. 替換 FoG 節點:在第 6.4 節中,探索使用 Raspberry Pi 替換 Jetson Nano 的可能性。
  4. 建立自有資料集:在第 6.4 節中,嘗試建立自己的資料集,並評估不同機器學習模型的效能。
  5. 引數調優:研究改變引數(如 C、degree 和 coefficient)對第 6.3 節系統準確度的影響,並評估使用 KNN 分類別器的準確度。
  6. 葡萄糖預測模型驗證:使用自建的葡萄糖感測器資料集來驗證葡萄糖預測模型的準確度。

透過這些練習和擴充套件,您可以更深入地理解機器學習在物聯網中的應用,並進一步提升相關技術的能力。