机器学习与物联网应用实践
1. 基于网页的机器学习模型应用
在这个应用场景中,我们将一个为 Python 编写的预训练模型,通过转换工具转换为适用于网页的形式。然后从 Web 服务中获取数据,并使用机器学习模型对其进行评估。当机器学习模型有 80% 的置信度认为涡轮风扇发动机即将达到剩余使用寿命的尽头时,会显示“Needs Maintenance”文本。
以下是相关的 HTML 代码示例:
<!DOCTYPE html>
<html>
<head>
<title>Model</title>
<script
src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs@1.0.0/dist/tf.min.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/@tensorflow/tfjs-vis@1.0.2/dist/tfjs-vis.umd.min.js"></script>
</head>
<body>
<button onclick="GetData()">Maintenance Needed</button>
<textarea id="data" style="width:400px;height:400px;"></textarea>
<div id="needed"></div>
</body>
<script
src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js">
</script>
<script type="text/javascript" src="index.js"></script>
</html>
近年来,网页浏览器的功能有了极大的提升,例如能够在后台处理和加工数据。像 Dexie 就是一个将数据添加到浏览器数据库的示例,同时现代浏览器还支持 Service Workers,它可以在后台运行,甚至在页面不活跃时也能工作。
2. 移动模型部署
许多物联网场景需要图形用户界面、较高的计算能力、蓝牙、Wi-Fi 和蜂窝网络,而大多数现代手机都具备这些功能。廉价的物联网设备可以通过蓝牙与智能手机上的应用程序通信,利用该应用程序执行机器学习任务并与云端交互。
使用手机可以缩短物联网设备的上市时间,这些设备可以通过安全且易于更新的应用程序将数据发送到云端。然而,手机的便携性既是优点也是缺点,因为设备持续与云端通信会快速耗尽手机电量,可能导致手机续航时间缩短至 8 小时。因此,企业通常会采用边缘处理来执行机器学习等计算任务,从而减少设备数据传输的频率。
在物联网应用中,手机的使用非常普遍。例如,Fitbit 和 Tile 等公司使用低功耗蓝牙(BLE)将数据发送到消费者的手机上,物联网设备本身可以采用低功耗设计,并将大部分工作负载卸载到连接的手机上。而像患者心脏监测仪、仓库库存工具和语音激活信息亭等设备,则可以设计专门的智能设备来满足应用需求。
接下来,我们将介绍如何在 Android 上使用 TensorFlow Lite,具体步骤如下:
1.
准备工作
- 下载并安装 Android Studio。
- 打开 Android Studio,从开始菜单中选择“+ Start a new Android Studio project”。
- 选择一个 UI 模板,这里我们选择空活动(Empty Activity)。
- 在下一步中,为项目命名并选择 Java 作为开发语言。
- 打开项目后,导入 TensorFlow Lite。具体操作是进入 Gradle Scripts 下的 build.gradle (Module: app) 部分,在 dependencies 部分添加以下引用:
implementation 'org.tensorflow:tensorflow-lite:+'
- 在 Android Studio 中,右键点击 app 文件夹,选择 New -> Folder -> Assets folder,这里将用于存放训练好的模型。可以使用 tflite 转换工具将模型进行转换。
-
具体操作步骤
- 在 MainActivity.java 文件的头部添加必要的 TensorFlow 引用:
import org.tensorflow.lite.Interpreter
- 在变量部分初始化 tflite 解释器:
Interpreter tflite;
- 在 OnCreate 方法中添加代码,将模型文件加载到 tflite 解释器中:
tflite = new Interpreter(loadModelFile(activity));
- 创建一个加载模型文件的方法:
private MappedByteBuffer loadModelFile(Activity activity) throws IOException {
AssetFileDescriptor fileDescriptor = activity.getAssets().openFd(getModelPath());
FileInputStream inputStream = new FileInputStream(fileDescriptor.getFileDescriptor());
FileChannel fileChannel = inputStream.getChannel();
long startOffset = fileDescriptor.getStartOffset();
long declaredLength = fileDescriptor.getDeclaredLength();
return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength);
}
- 在从蓝牙数据馈送调用的方法中执行必要的推理:
tflite.run(inputdata, labelProbArray);
3. 使用设备孪生维护设备群
设备孪生是一组用于管理设备群的工具,它可以将信息传递给设备,例如设备应使用的模型;也可以将更多状态信息传回云端,例如模型的实际错误率。
设备孪生分为设备端和云端两部分。设备端有一个类似可写配置文件的 JSON 文件,云端则有一个可写的属性数据库,这两部分会有序同步,方便我们管理设备群。
设备孪生的一个优点是可以查看模型部署是否成功。在物联网产品的生命周期中,机器学习模型会随着信息的变化而更新,新模型会被推送到设备上,但这些模型可能会引发内存不足异常或导致设备故障。此外,当制造商变更或某些组件不可用时,硬件也可能会被替换。
设备孪生由三部分组成:
-
标签区域(Tags Area)
:负责存储设备的通用标签,如设备名称、位置或所有者等信息,这些数据由云端设置。
-
期望属性(Desired Properties)
:同样由云端设置,代表云端希望设备达到的状态,例如模型版本或阈值。
-
报告属性(Reported Properties)
:由设备设置,可以是数据值或对期望属性的响应。
如果期望属性(如模型版本)发生变化,我们可以尝试更新到最新版本,并在更新成功后将报告属性设置为期望版本;如果更新失败,可以在云端进行查询。我们还可以使用标签区域将设备分组进行更新,实现滚动更新,即先更新少量设备,再逐步更新更多设备,也可以根据设备的特定特征(如位置和所有者)部署不同的模型。
下面是使用 Azure IoT Hub 和 Python 实现设备孪生的具体步骤:
1.
准备工作
- Python 版本需高于 3.6,安装以下库:
pip3 install azure-iot-device
pip3 install asyncio
- 从 IoT Hub 获取设备连接字符串。具体操作是进入创建的 IoT Hub,点击左侧面板的“IoT Devices”菜单项,点击“+”按钮添加一个使用对称密钥认证的设备,点击该设备获取设备密钥。
- 进入共享访问策略菜单项,复制服务策略连接字符串,用于连接 IoT Hub 管理设备群。
-
设备端操作步骤
- 导入必要的库:
import asyncio
from six.moves import input
from azure.iot.device.aio import IoTHubDeviceClient
- 创建 main() 函数并连接到设备:
async def main():
device_client = IoTHubDeviceClient.create_from_connection_string("Connection String")
await device_client.connect()
- 创建一个孪生监听器:
def quit_listener():
while True:
selection = input("Press Q to quit\n")
if selection == "Q" or selection == "q":
print("Quitting...")
break
- 创建一个监听任务:
asyncio.create_task(twin_patch_listener(device_client))
- 监听退出信号:
loop = asyncio.get_running_loop()
user_finished = loop.run_in_executor(None, quit_listener)
- 等待用户结束信号并断开连接:
await user_finished
await device_client.disconnect()
- 使用 asyncio 运行循环:
if __name__ == "__main__":
asyncio.run(main())
-
云端操作步骤
- 导入必要的库:
import sys
from time import sleep
from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import Twin, TwinProperties
- 使用服务连接字符串连接到 IoT Hub:
iothub_registry_manager = IoTHubRegistryManager("Service Connection String")
- 设置期望属性为模型版本:
twin = iothub_registry_manager.get_twin("Device_id")
twin_patch = Twin(properties=TwinProperties(desired={'Vision_Model_Version': 1.2}))
twin = iothub_registry_manager.update_twin(DEVICE_ID, twin_patch, twin.etag)
- 在另一个 Python 文件中查询设备版本是否更新:
import sys
from time import sleep
from azure.iot.hub import IoTHubRegistryManager
from azure.iot.hub.models import Twin, TwinProperties, QuerySpecification, QueryResult
query_spec = QuerySpecification(query="SELECT * FROM devices WHERE properties.reported.Vision_Model_Version <> 1.2")
query_result = iothub_registry_manager.query_iot_hub(query_spec, None, 100)
print("Devices that did not update: {}".format(', '.join([twin.device_id for twin in query_result.items])))
4. 分布式机器学习与雾计算
在物联网领域,通常需要处理大量数据,传感器会产生大量信息,设备规模也较大。例如,欧洲核子研究中心(CERN)的粒子加速器每秒会产生超过 1PB 的数据,将这些原始数据发送到中央存储库是不现实的。许多面临超大型数据集或高速移动数据集的公司在处理数据时会遇到挑战。
在这个场景中,我们将通过雾计算将工作负载分布到多个系统中,让一个系统负责采集图像,另一个系统负责处理图像。例如,小型设备可以采集图像并将其流式传输到工厂中的工业 PC 或服务器组。我们将使用 Docker 和 Docker Compose,算法采用 YOLO(一种图像分类算法)的 OpenCV 实现。
下面是具体的操作步骤:
1.
准备工作
- 使用 VS Code 的 Docker 扩展在 Docker 容器中工作。
- 准备一个连接了网络摄像头的设备,可以是笔记本电脑或带有摄像头的树莓派。
- 设置机器学习服务、摄像头流服务以及一个让设备相互定位的服务,以便在整个设备群中查看分类结果。为了简洁起见,这里只展示计算机视觉模块的代码,其他模块可以使用 Docker 和相关代码在 GitHub 仓库中运行。
2.
具体操作步骤
- 在计算设备上下载 YOLO 的机器学习模型文件:
wget https://pjreddie.com/media/files/yolov3.weights
wget https://raw.githubusercontent.com/microshak/AI_Benchtest_Device/yolov3.txt
wget https://raw.githubusercontent.com/microshak/AI_Benchtest_Device/yolov3.cfg
- 创建一个 CPU 文件夹并在其中创建一个 __init__.py 文件:
from flask import Flask
cpu = Flask(__name__)
from CPU.Yolo import yolo
from CPU.manifest import manifest
cpu.register_blueprint(yolo)
cpu.register_blueprint(manifest)
- 创建一个 manifest.py 文件,将计算服务器的功能信息发送到中央服务器:
from flask_apscheduler import APScheduler
from flask import Blueprint, request, jsonify, session
import requests
import socket
import json
import os
manifest = Blueprint('manifest', 'manifest', url_prefix='/manifest')
scheduler = APScheduler()
def set_manifest():
f = open("manifest_cpu.json", "r")
manifest = f.read()
data = json.loads(manifest)
data['host_name'] = socket.gethostname()
gw = os.popen("ip -4 route show default").read().split()
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect((gw[2], 0))
ipaddr = s.getsockname()[0]
data['ip_address'] = ipaddr
url = 'https://ai-benchtest.azurewebsites.net/device'
r = requests.post(url=url, json=data)
txt = r.text
set_manifest()
scheduler.add_job(id='Scheduled task', func=set_manifest, trigger='interval', minutes=10)
scheduler.start()
- 创建一个 Yolo.py 文件并导入必要的库:
import cv2
import pickle
from io import BytesIO
import time
import requests
from PIL import Image
import numpy as np
from importlib import import_module
import os
from flask import Flask, render_template, Response
from flask import request
import imutils
import json
import requests
from flask import Blueprint, request, jsonify, session
- 初始化页面为 Flask 页面:
yolo = Blueprint('yolo', 'yolo', url_prefix='/yolo')
- 初始化绘图变量:
classes = None
COLORS = np.random.uniform(0, 300, size=(len(classes), 3))
- 导入模型类名:
with open("yolov3.txt", 'r') as f:
classes = [line.strip() for line in f.readlines()]
- 创建一个辅助函数来获取输出层:
def get_output_layers(net):
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
return output_layers
- 创建一个辅助函数,在识别的对象周围绘制矩形并插入分类文本:
def draw_prediction(img, class_id, confidence, x, y, x_plus_w, y_plus_h):
label = str(classes[class_id])
color = COLORS[class_id]
cv2.rectangle(img, (x, y), (x_plus_w, y_plus_h), color, 2)
cv2.putText(img, label, (x - 10, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)
- 创建一个 Yolo 方法,接收图像和神经网络并对图像进行下采样:
def Yolo(image, net):
try:
Width = image.shape[1]
Height = image.shape[0]
scale = 0.00392
blob = cv2.dnn.blobFromImage(image, scale, (416, 416), (0, 0, 0), True, crop=False)
- 将图像作为输入传递给神经网络并进行 YOLO 分析:
net.setInput(blob)
outs = net.forward(get_output_layers(net))
- 初始化变量并设置置信度阈值:
class_ids = []
confidences = []
boxes = []
conf_threshold = 0.5
nms_threshold = 0.4
- 将机器学习结果转换为可应用于图像的坐标:
for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5:
center_x = int(detection[0] * Width)
center_y = int(detection[1] * Height)
w = int(detection[2] * Width)
h = int(detection[3] * Height)
x = center_x - w / 2
y = center_y - h / 2
class_ids.append(class_id)
confidences.append(float(confidence))
boxes.append([x, y, w, h])
- 抑制不符合阈值标准的边界框:
indices = cv2.dnn.NMSBoxes(boxes, confidences, conf_threshold, nms_threshold)
- 获取边界框并在图像中绘制:
for i in indices:
i = i[0]
box = boxes[i]
x = box[0]
y = box[1]
w = box[2]
h = box[3]
draw_prediction(image, class_ids[i], confidences[i], round(x), round(y), round(x + w), round(y + h))
- 返回处理后的图像:
return image
- 创建一个名为 gen 的函数,导入模型并持续从摄像头设备获取图像:
def gen(height, width, downsample, camera):
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
while True:
url = f'http://{camera}:5000/image.jpg?height={height}&width={width}'
r = requests.get(url)
curr_img = Image.open(BytesIO(r.content))
- 调整图像大小和颜色:
frame = cv2.cvtColor(np.array(curr_img), cv2.COLOR_RGB2BGR)
dwidth = float(width) * (1 - float(downsample))
dheight = float(height) * (1 - float(downsample))
frame = imutils.resize(frame, width=int(dwidth), height=int(dheight))
- 执行机器学习算法并流式传输结果:
frame = Yolo(frame, net)
frame = cv2.imencode('.jpg', frame)[1].tobytes()
yield (b'--frame\r\n'
b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n')
- 创建一个 Web 地址,获取 URL 参数并通过算法处理:
@yolo.route('/image.jpg')
def image():
height = request.args.get('height')
width = request.args.get('width')
downsample = request.args.get('downsample')
camera = request.args.get('camera')
return Response(gen(height, width, downsample, camera), mimetype='multipart/x-mixed-replace; boundary=frame')
- 在根文件夹中创建一个 manifest.json 文件,广播使用的机器的功能:
{
"FriendlyName": "Thinkstation"
}
通过以上步骤,我们可以实现基于网页的机器学习模型应用、移动模型部署、设备孪生管理以及分布式机器学习与雾计算,为物联网应用提供更高效、更智能的解决方案。
机器学习与物联网应用实践(续)
5. 各方案的优势与应用场景总结
为了更清晰地了解上述几种机器学习与物联网结合方案的特点,我们可以通过以下表格进行对比:
| 方案 | 优势 | 应用场景 |
| — | — | — |
| 基于网页的机器学习模型应用 | 可利用网页的广泛传播性,方便用户通过浏览器访问模型;能实时从 Web 服务获取数据进行评估 | 适用于需要实时展示模型评估结果,且面向大众用户的场景,如设备维护预警展示 |
| 移动模型部署 | 借助手机的强大功能,缩短物联网设备上市时间;可利用手机安全且易更新的应用与云端交互 | 适用于需要图形界面和较高计算能力的物联网场景,如可穿戴设备数据传输 |
| 使用设备孪生维护设备群 | 方便管理设备群,可查看模型部署效果;能实现滚动更新和根据设备特征部署不同模型 | 适用于大规模设备管理和模型更新的场景,如工业物联网设备管理 |
| 分布式机器学习与雾计算 | 解决大数据传输难题,将工作负载分布到多个系统;减少设备与云端的数据传输量 | 适用于处理大量数据和高速数据的物联网场景,如工业生产中的图像识别 |
6. 技术实现流程梳理
下面通过 mermaid 流程图来梳理在 Android 上使用 TensorFlow Lite 的技术实现流程:
graph LR
A[下载并安装 Android Studio] --> B[创建新 Android 项目]
B --> C[选择 UI 模板(空活动)]
C --> D[为项目命名并选 Java 语言]
D --> E[导入 TensorFlow Lite]
E --> F[创建 Assets 文件夹存放模型]
F --> G[在 MainActivity.java 头部添加引用]
G --> H[初始化 tflite 解释器]
H --> I[在 OnCreate 方法加载模型文件]
I --> J[创建加载模型文件的方法]
J --> K[在蓝牙数据馈送方法中执行推理]
同样,我们也可以用流程图梳理使用 Azure IoT Hub 和 Python 实现设备孪生的流程:
graph LR
A[安装必要 Python 库] --> B[从 IoT Hub 获取设备连接字符串]
B --> C[复制服务策略连接字符串]
C --> D[设备端导入必要库]
D --> E[创建 main 函数连接设备]
E --> F[创建孪生监听器]
F --> G[创建监听任务]
G --> H[监听退出信号]
H --> I[等待用户结束信号并断开连接]
I --> J[使用 asyncio 运行循环]
C --> K[云端导入必要库]
K --> L[连接 IoT Hub]
L --> M[设置期望属性为模型版本]
M --> N[查询设备版本是否更新]
7. 代码优化与注意事项
在实际应用中,上述代码可能需要进行优化以提高性能和稳定性。以下是一些建议:
-
基于网页的机器学习模型应用
:
- 对从 Web 服务获取的数据进行缓存,减少重复请求,提高响应速度。
- 优化 HTML 和 JavaScript 代码,减少页面加载时间。
-
移动模型部署
:
- 对模型进行量化处理,减少模型大小,降低内存占用。
- 优化蓝牙通信协议,减少数据传输延迟和功耗。
-
使用设备孪生维护设备群
:
- 定期清理设备端和云端的无效数据,避免数据库膨胀。
- 对模型更新过程进行监控,及时处理更新失败的情况。
-
分布式机器学习与雾计算
:
- 优化 Docker 容器的资源分配,提高计算效率。
- 对图像数据进行预处理,减少数据量,提高模型处理速度。
同时,在使用这些技术时还需要注意以下事项:
- 确保网络连接稳定,特别是在设备与云端交互和数据传输过程中。
- 注意数据安全,对敏感数据进行加密处理。
- 遵循相关开源库和框架的使用协议,避免法律风险。
8. 未来发展趋势展望
随着物联网和机器学习技术的不断发展,这些应用方案也将不断演进。未来可能会出现以下发展趋势:
-
更强大的边缘计算能力
:边缘设备的计算能力将不断提升,能够在本地完成更多复杂的机器学习任务,进一步减少对云端的依赖。
-
更智能的设备管理
:设备孪生技术将与人工智能结合,实现更智能的设备故障预测和自动修复,提高设备的可靠性和可用性。
-
更广泛的应用场景
:机器学习与物联网的结合将拓展到更多领域,如智能家居、智能交通、医疗健康等,为人们的生活带来更多便利。
通过不断探索和实践,我们可以更好地利用这些技术,推动物联网和机器学习的发展,创造更智能、更高效的未来。
综上所述,机器学习与物联网的结合为我们带来了更多的可能性和机遇。通过合理选择和应用上述方案,我们可以为不同的物联网场景提供更优质的解决方案,满足各种实际需求。在未来的发展中,我们应持续关注技术的进步,不断优化和创新,以适应不断变化的市场和用户需求。
超级会员免费看
1061

被折叠的 条评论
为什么被折叠?



