Sztuczna inteligencja na brzegu to jeden z najpopularniejszych scenariuszy brzegowych. Implementacje tego scenariusza obejmują klasyfikację obrazów, wykrywanie obiektów, treść, twarz i analizę gestów oraz manipulowanie obrazami. W tym przewodniku po architekturze opisano sposób używania usługi Azure IoT Edge do obsługi tych scenariuszy.
Dokładność sztucznej inteligencji można poprawić, aktualizując model AI, ale w niektórych scenariuszach środowisko sieciowe urządzenia brzegowego nie jest dobre. Na przykład w przemyśle wiatrowym i naftowym sprzęt może znajdować się na pustyni lub w oceanie.
Bliźniacze reprezentacje modułów usługi IoT Edge służą do implementowania dynamicznie ładowanego modelu sztucznej inteligencji. Moduły usługi IoT Edge są oparte na platformie Docker. Obraz modułu usługi IoT Edge w środowisku sztucznej inteligencji zwykle ma rozmiar co najmniej 1 GB, więc przyrostowe aktualizowanie modelu AI jest ważne w sieci o wąskiej przepustowości. To zagadnienie jest głównym celem tego artykułu. Chodzi o utworzenie modułu AI usługi IoT Edge, który może ładować modele wykrywania obiektów LiteRT (dawniej TensorFlow Lite) lub Open Neural Network Exchange (ONNX). Możesz również włączyć moduł jako internetowy interfejs API, aby umożliwić korzystanie z niego w celu korzystania z innych aplikacji lub modułów.
Rozwiązanie opisane w tym artykule może pomóc w następujący sposób:
- Włącz wnioskowanie sztucznej inteligencji na urządzeniach brzegowych.
- Zminimalizuj koszt sieci wdrażania i aktualizowania modeli sztucznej inteligencji na urządzeniach brzegowych. Rozwiązanie może zaoszczędzić pieniądze dla Ciebie lub Twoich klientów, zwłaszcza w środowisku sieci o wąskiej przepustowości.
- Tworzenie repozytorium modelu AI i zarządzanie nim w lokalnym magazynie urządzenia usługi IoT Edge.
- Osiągnij niemal zerowy przestój, gdy urządzenie brzegowe przełącza modele sztucznej inteligencji.
TensorFlow i LiteRT są znakiem towarowym Google Inc. Żadne poparcie nie jest implikowane przez użycie tego znaku towarowego.
Architektura
Pobierz plik programu Visio z tą architekturą.
Przepływ danych
- Model sztucznej inteligencji jest przekazywany do usługi Azure Blob Storage lub usługi internetowej. Model może być wstępnie wytrenowanym modelem LiteRT lub ONNX albo modelem utworzonym w usłudze Azure Machine Learning. Moduł usługi IoT Edge może uzyskać dostęp do tego modelu i pobrać go do urządzenia brzegowego później. Jeśli potrzebujesz lepszych zabezpieczeń, rozważ użycie połączeń prywatnych punktów końcowych między usługą Blob Storage i urządzeniem brzegowym.
- Usługa Azure IoT Hub synchronizuje bliźniacze reprezentacje modułu urządzenia automatycznie z informacjami o modelu AI. Synchronizacja odbywa się nawet wtedy, gdy usługa IoT Edge była w trybie offline. (W niektórych przypadkach urządzenia IoT są połączone z sieciami w zaplanowanych godzinach, codziennie lub co tydzień w celu zaoszczędzenia zasilania lub zmniejszenia ruchu sieciowego).
- Moduł modułu ładującego monitoruje aktualizacje bliźniaczych reprezentacji modułu za pośrednictwem interfejsu API. Po wykryciu aktualizacji pobiera token SAS modelu uczenia maszynowego, a następnie pobiera model AI.
- Aby uzyskać więcej informacji, zobacz Tworzenie tokenu SAS dla kontenera lub obiektu blob.
- Możesz użyć właściwości ExpiresOn , aby ustawić datę wygaśnięcia zasobów. Jeśli urządzenie będzie w trybie offline przez długi czas, możesz przedłużyć czas wygaśnięcia.
- Moduł modułu ładującego zapisuje model AI w udostępnionym magazynie lokalnym modułu usługi IoT Edge. Musisz skonfigurować udostępniony magazyn lokalny w pliku JSON wdrożenia usługi IoT Edge.
- Moduł modułu ładującego ładuje model AI z magazynu lokalnego za pośrednictwem interfejsu API LiteRT lub ONNX.
- Moduł modułu ładującego uruchamia internetowy interfejs API, który odbiera zdjęcie binarne za pośrednictwem żądania POST i zwraca wyniki w pliku JSON.
Aby zaktualizować model AI, możesz przekazać nową wersję do usługi Blob Storage i ponownie zsynchronizować bliźniacze reprezentacje modułu urządzenia w celu aktualizacji przyrostowej. Nie ma potrzeby aktualizowania całego obrazu modułu usługi IoT Edge.
Szczegóły scenariusza
W tym rozwiązaniu moduł usługi IoT Edge służy do pobierania modelu sztucznej inteligencji, a następnie włączania wnioskowania uczenia maszynowego. W tym rozwiązaniu można używać wstępnie wytrenowanych modeli LiteRT lub ONNX.
LiteRT
Plik
.tflite
jest wstępnie wytrenowanym modelem sztucznej inteligencji. Możesz pobrać go z TensorFlow.org. Jest to ogólny model sztucznej inteligencji, którego można używać w aplikacjach międzyplatformowych, takich jak iOS i Android. Oprogramowanie LiteRT obsługuje modele z bibliotek TensorFlow, PyTorch, JAX i Keras. Aby uzyskać więcej informacji na temat metadanych i skojarzonych pól (na przykładlabels.txt
), zobacz Odczytywanie metadanych z modeli.Model wykrywania obiektów jest trenowany w celu wykrywania obecności i lokalizacji wielu klas obiektów. Na przykład model może być wytrenowany za pomocą obrazów zawierających różne kawałki owoców, wraz z etykietą określającą klasę owoców reprezentujących (na przykład jabłko) i dane określające, gdzie każdy obiekt pojawia się na obrazie.
Gdy obraz jest dostarczany do modelu, zwraca listę wykrytych obiektów, lokalizację pola ograniczenia dla każdego obiektu oraz wynik wskazujący pewność wykrywania.
Jeśli chcesz utworzyć lub dostosować niestandardowy model AI, zobacz LiteRT Model Maker.
W zoo wykrywania wykrywania można uzyskać więcej bezpłatnych wstępnie wytrenowanych modeli wykrywania, z różnymi właściwościami opóźnienia i precyzji. Każdy model używa podpisów wejściowych i wyjściowych przedstawionych w poniższych przykładach kodu.
ONNX
ONNX to standardowy format reprezentujący modele uczenia maszynowego. Jest ona wspierana przez społeczność partnerów, którzy wdrożyli ją w wielu strukturach i narzędziach.
- USŁUGA ONNX obsługuje narzędzia do tworzenia i wdrażania modeli oraz wykonywania innych zadań. Aby uzyskać więcej informacji, zobacz Obsługiwane narzędzia ONNX.
- Środowisko uruchomieniowe ONNX umożliwia uruchamianie wstępnie wytrenowanych modeli ONNX. Aby uzyskać informacje o wstępnie wytrenowanych modelach, zobacz ONNX Model Zoo.
- W tym scenariuszu można użyć modelu wykrywania obiektów i segmentacji obrazów: Tiny YOLOv3.
Społeczność ONNX udostępnia narzędzia ułatwiające tworzenie i wdrażanie modelu uczenia głębokiego.
Pobieranie wytrenowanych modeli sztucznej inteligencji
Aby pobrać wytrenowane modele sztucznej inteligencji, zalecamy używanie bliźniaczych reprezentacji urządzeń do odbierania powiadomień, gdy nowy model jest gotowy. Nawet jeśli urządzenie jest w trybie offline, komunikat można buforować w usłudze IoT Hub, dopóki urządzenie brzegowe nie wróci do trybu online. Wiadomość zostanie zsynchronizowana automatycznie.
Poniżej przedstawiono przykład kodu w języku Python, który rejestruje powiadomienia dla bliźniaczych reprezentacji urządzenia, a następnie pobiera model sztucznej inteligencji w pliku ZIP. Wykonuje również dalsze operacje na pobranym pliku.
Kod wykonuje następujące zadania:
- Odbieranie powiadomienia bliźniaczych reprezentacji urządzenia. Powiadomienie zawiera nazwę pliku, adres pobierania pliku i token uwierzytelniania MD5. (W nazwie pliku można uwzględnić informacje o wersji, takie jak 1.0).
- Pobierz model AI jako plik ZIP do magazynu lokalnego.
- Opcjonalnie wykonaj sumę kontrolną MD5. Weryfikacja MD5 pomaga zapobiec naruszeniu plików ZIP podczas transmisji sieci.
- Rozpakuj plik ZIP i zapisz go lokalnie.
- Wyślij powiadomienie do usługi IoT Hub lub komunikat routingu, aby zgłosić, że nowy model sztucznej inteligencji jest gotowy.
# define behavior for receiving a twin patch
async def twin_patch_handler(patch):
try:
print( "######## The data in the desired properties patch was: %s" % patch)
if "FileName" in patch:
FileName = patch["FileName"]
if "DownloadUrl" in patch:
DownloadUrl = patch["DownloadUrl"]
if "ContentMD5" in patch:
ContentMD5 = patch["ContentMD5"]
FilePath = "/iotedge/storage/" + FileName
# download AI model
r = requests.get(DownloadUrl)
print ("######## download AI Model Succeeded.")
ffw = open(FilePath, 'wb')
ffw.write(r.content)
ffw.close()
print ("######## AI Model File: " + FilePath)
# MD5 checksum
md5str = content_encoding(FilePath)
if md5str == ContentMD5:
print ( "######## New AI Model MD5 checksum succeeded")
# decompressing the ZIP file
unZipSrc = FilePath
targeDir = "/iotedge/storage/"
filenamenoext = get_filename_and_ext(unZipSrc)[0]
targeDir = targeDir + filenamenoext
unzip_file(unZipSrc,targeDir)
# ONNX
local_model_path = targeDir + "/tiny-yolov3-11.onnx"
local_labelmap_path = targeDir + "/coco_classes.txt"
# LiteRT
# local_model_path = targeDir + "/ssd_mobilenet_v1_1_metadata_1.tflite"
# local_labelmap_path = targeDir + "/labelmap.txt"
# message to module
if client is not None:
print ( "######## Send AI Model Info AS Routing Message")
data = "{\"local_model_path\": \"%s\",\"local_labelmap_path\": \"%s\"}" % (filenamenoext+"/tiny-yolov3-11.onnx", filenamenoext+"/coco_classes.txt")
await client.send_message_to_output(data, "DLModelOutput")
# update the reported properties
reported_properties = {"LatestAIModelFileName": FileName }
print("######## Setting reported LatestAIModelName to {}".format(reported_properties["LatestAIModelFileName"]))
await client.patch_twin_reported_properties(reported_properties)
else:
print ( "######## New AI Model MD5 checksum failed")
except Exception as ex:
print ( "Unexpected error in twin_patch_handler: %s" % ex )
Wnioskowanie
Po pobraniu modelu sztucznej inteligencji następnym krokiem jest użycie modelu na urządzeniu brzegowym. Model można dynamicznie ładować i przeprowadzać wykrywanie obiektów na urządzeniach brzegowych. W poniższym przykładzie kodu pokazano, jak używać modelu AI LiteRT do wykrywania obiektów na urządzeniach brzegowych.
Kod wykonuje następujące zadania:
- Dynamiczne ładowanie modelu LiteRT AI.
- Wykonaj standaryzację obrazu.
- Wykrywanie obiektów.
- Wyniki wykrywania obliczeń.
class InferenceProcedure():
def detect_object(self, imgBytes):
results = []
try:
model_full_path = AI_Model_Path.Get_Model_Path()
if(model_full_path == ""):
raise Exception ("PLEASE SET AI MODEL FIRST")
if '.tflite' in model_full_path:
interpreter = tf.lite.Interpreter(model_path=model_full_path)
interpreter.allocate_tensors()
input_details = interpreter.get_input_details()
output_details = interpreter.get_output_details()
input_shape = input_details[0]['shape']
# bytes to numpy.ndarray
im_arr = np.frombuffer(imgBytes, dtype=np.uint8)
img = cv2.imdecode(im_arr, flags=cv2.IMREAD_COLOR)
im_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
im_rgb = cv2.resize(im_rgb, (input_shape[1], input_shape[2]))
input_data = np.expand_dims(im_rgb, axis=0)
interpreter.set_tensor(input_details[0]['index'], input_data)
interpreter.invoke()
output_data = interpreter.get_tensor(output_details[0]['index'])
detection_boxes = interpreter.get_tensor(output_details[0]['index'])
detection_classes = interpreter.get_tensor(output_details[1]['index'])
detection_scores = interpreter.get_tensor(output_details[2]['index'])
num_boxes = interpreter.get_tensor(output_details[3]['index'])
label_names = [line.rstrip('\n') for line in open(AI_Model_Path.Get_Labelmap_Path())]
label_names = np.array(label_names)
new_label_names = list(filter(lambda x : x != '???', label_names))
for i in range(int(num_boxes[0])):
if detection_scores[0, i] > .5:
class_id = int(detection_classes[0, i])
class_name = new_label_names[class_id]
# top, left, bottom, right
results_json = "{'Class': '%s','Score': '%s','Location': '%s'}" % (class_name, detection_scores[0, i],detection_boxes[0, i])
results.append(results_json)
print(results_json)
except Exception as e:
print ( "detect_object unexpected error %s " % e )
raise
# return results
return json.dumps(results)
Poniżej znajduje się wersja ONNX poprzedniego kodu. Kroki są w większości takie same. Jedyną różnicą jest sposób obsługi wyniku wykrywania, ponieważ Labelmap
parametry wyjściowe modelu i są różne.
class InferenceProcedure():
def letterbox_image(self, image, size):
'''resize image with unchanged aspect ratio using padding'''
iw, ih = image.size
w, h = size
scale = min(w/iw, h/ih)
nw = int(iw*scale)
nh = int(ih*scale)
image = image.resize((nw,nh), Image.BICUBIC)
new_image = Image.new('RGB', size, (128,128,128))
new_image.paste(image, ((w-nw)//2, (h-nh)//2))
return new_image
def preprocess(self, img):
model_image_size = (416, 416)
boxed_image = self.letterbox_image(img, tuple(reversed(model_image_size)))
image_data = np.array(boxed_image, dtype='float32')
image_data /= 255.
image_data = np.transpose(image_data, [2, 0, 1])
image_data = np.expand_dims(image_data, 0)
return image_data
def detect_object(self, imgBytes):
results = []
try:
model_full_path = AI_Model_Path.Get_Model_Path()
if(model_full_path == ""):
raise Exception ("PLEASE SET AI MODEL FIRST")
if '.onnx' in model_full_path:
# input
image_data = self.preprocess(imgBytes)
image_size = np.array([imgBytes.size[1], imgBytes.size[0]], dtype=np.float32).reshape(1, 2)
labels_file = open(AI_Model_Path.Get_Labelmap_Path())
labels = labels_file.read().split("\n")
# Loading ONNX model
print("loading Tiny YOLO...")
start_time = time.time()
sess = rt.InferenceSession(model_full_path)
print("loaded after", time.time() - start_time, "s")
input_name00 = sess.get_inputs()[0].name
input_name01 = sess.get_inputs()[1].name
pred = sess.run(None, {input_name00: image_data,input_name01:image_size})
boxes = pred[0]
scores = pred[1]
indices = pred[2]
results = []
out_boxes, out_scores, out_classes = [], [], []
for idx_ in indices[0]:
out_classes.append(idx_[1])
out_scores.append(scores[tuple(idx_)])
idx_1 = (idx_[0], idx_[2])
out_boxes.append(boxes[idx_1])
results_json = "{'Class': '%s','Score': '%s','Location': '%s'}" % (labels[idx_[1]], scores[tuple(idx_)],boxes[idx_1])
results.append(results_json)
print(results_json)
except Exception as e:
print ( "detect_object unexpected error %s " % e )
raise
# return results
return json.dumps(results)
Jeśli urządzenie usługi IoT Edge zawiera powyższy kod i funkcje, urządzenie brzegowe ma wykrywanie obiektów obrazów sztucznej inteligencji i obsługuje dynamiczną aktualizację modeli sztucznej inteligencji. Jeśli chcesz, aby moduł brzegowy udostępniał funkcje sztucznej inteligencji innym aplikacjom lub modułom za pośrednictwem internetowego interfejsu API, możesz utworzyć internetowy interfejs API w module.
Platforma Flask jest jednym z przykładów narzędzia, którego można użyć do szybkiego tworzenia interfejsu API. Obrazy można odbierać jako dane binarne, używać modelu AI do wykrywania, a następnie zwracać wyniki w formacie JSON. Aby uzyskać więcej informacji, zobacz Flask: Flask Tutorial in Visual Studio Code (Samouczek platformy Flask: flask w programie Visual Studio Code).
Współautorzy
Ten artykuł jest obsługiwany przez firmę Microsoft. Pierwotnie został napisany przez następujących współautorów.
Główny autor:
- Bo Wang | Starszy inżynier oprogramowania
Inny współautor:
- Freddy Ayala | Architekt rozwiązań w chmurze
Aby wyświetlić niepubalne profile serwisu LinkedIn, zaloguj się do serwisu LinkedIn.
Następne kroki
- Opis bliźniaczych reprezentacji modułów i korzystanie z nich w usłudze IoT Hub
- Learn how to deploy modules and establish routes in IoT Edge (Dowiedz się, jak wdrażać moduły i ustanawiać trasy w usłudze IoT Edge).
- Przyznawanie modułom dostępu do magazynu lokalnego urządzenia
- Omówienie automatycznych wdrożeń usługi IoT Edge dla pojedynczych urządzeń lub na dużą skalę
- Otwórz wymianę sieci neuronowej
- Samouczki ONNX
- Wdrażanie modelu uczenia maszynowego na urządzeniach IoT i edge