Bearbeiten

Freigeben über


Aktivieren von Machine Learning-Rückschlüssen auf einem Azure IoT Edge-Gerät

Azure IoT Edge
Azure IoT Hub

KI am Edge ist eines der beliebtesten Edge-Szenarien. Implementierungen dieses Szenarios umfassen Bildklassifizierung, Objekterkennung, Körper-, Gesichts- und Gestenanalyse sowie Bildbearbeitung. In diesem Architekturhandbuch wird beschrieben, wie Sie Azure IoT Edge verwenden, um diese Szenarien zu unterstützen.

Sie können die KI-Genauigkeit verbessern, indem Sie das KI-Modell aktualisieren, aber in einigen Szenarien ist die Netzwerkumgebung des Edgegeräts nicht gut. In der Windkraft- und Ölindustrie kann sich die Ausrüstung beispielsweise in der Wüste oder im Meer befinden.

IoT Edge-Modulzwillinge werden verwendet, um das dynamisch geladene KI-Modell zu implementieren. IoT Edge-Module basieren auf Docker. Ein Image für ein IoT Edge-Modul in einer KI-Umgebung hat in der Regel eine Größe von mindestens 1 GB. Daher ist die inkrementelle Aktualisierung des KI-Modells in einem Netzwerk mit geringer Bandbreite wichtig. Diese Überlegungen stehen im Mittelpunkt dieses Artikels. Die Idee besteht darin, ein IoT Edge KI-Modul zu erstellen, das TensorFlow Lite- oder ONNX-Objekterkennungsmodelle (Open Neural Network Exchange) laden kann. Sie können das Modul auch als Web-API aktivieren, sodass Sie es für andere Anwendungen oder Module verwenden können.

Die in diesem Artikel beschriebene Lösung kann Ihnen wie folgt helfen:

  • Aktivieren Sie KI-Rückschlüsse auf Edgegeräten.
  • Minimieren Sie die Netzwerkkosten für die Bereitstellung und Aktualisierung von KI-Modellen am Edge. Mit dieser Lösung können Sie oder Ihre Kunden Geld sparen, insbesondere in einer Netzwerkumgebung mit geringer Bandbreite.
  • Erstellen und verwalten Sie ein KI-Modell-Repository im lokalen Speicher eines IoT Edge-Geräts.
  • Erzielen Sie nahezu null Ausfallzeiten, wenn das Edgegerät KI-Modelle wechselt.

TensorFlow ist eine Marke von Google Inc. Durch die Verwendung dieser Marke wird keine Billigung impliziert.

Architektur

Diagramm mit einer Architektur, die Rückschlüsse auf maschinelles Lernen unterstützt.

Laden Sie eine Visio-Datei dieser Architektur herunter.

Datenfluss

  1. Das KI-Modell wird in Azure Blob Storage oder einen Webdienst hochgeladen. Das Modell kann ein vortrainiertes TensorFlow Lite- oder ONNX-Modell oder ein in Azure Machine Learning erstelltes Modell sein. Das IoT Edge-Modul kann auf dieses Modell zugreifen und es später auf das Edgegerät herunterladen. Wenn Sie mehr Sicherheit benötigen, sollten Sie private Endpunktverbindungen zwischen Blob Storage und dem Edgegerät verwenden.
  2. Azure IoT Hub synchronisiert Geräte-Modulzwillinge automatisch mit KI-Modellinformationen. Die Synchronisierung erfolgt auch dann, wenn IoT Edge offline war. (In einigen Fällen sind IoT-Geräte stündlich, täglich oder wöchentlich mit Netzwerken verbunden, um Energie zu sparen oder Netzwerkdatenverkehr zu reduzieren.)
  3. Das Lademodul überwacht die Updates der Modulzwillinge über die API. Wenn ein Update erkannt wird, ruft es das SAS-Token des Machine Learning-Modells ab und lädt das KI-Modell herunter.
  4. Das Lademodul speichert das KI-Modell im freigegebenen lokalen Speicher des IoT Edge-Moduls. Sie müssen den freigegebenen lokalen Speicher in der JSON-Datei der IoT Edge-Bereitstellung konfigurieren.
  5. Das Lademodul lädt das KI-Modell aus dem lokalen Speicher über die TensorFlow Lite- oder ONNX-API.
  6. Das Lademodul startet eine Web-API, die das binäre Foto per POST-Anforderung empfängt und die Ergebnisse in einer JSON-Datei zurückgibt.

Um das KI-Modell zu aktualisieren, können Sie die neue Version in Blob Storage hochladen und die Geräte-Modulzwillinge für ein inkrementelles Update erneut synchronisieren. Es ist nicht erforderlich, das gesamte IoT Edge-Modulimage zu aktualisieren.

Szenariodetails

In dieser Lösung wird ein IoT Edge-Modul verwendet, um ein KI-Modell herunterzuladen und dann Machine Learning-Rückschlüsse zu aktivieren. Sie können in dieser Lösung vortrainierte TensorFlow Lite- oder ONNX-Modelle verwenden.

In den nächsten beiden Abschnitten werden einige Konzepte zu Machine Learning-Rückschlussmodulen, TensorFlow Lite und ONNX erläutert.

TensorFlow Lite

  • Eine *.tflite-Datei ist ein vortrainiertes KI-Modell. Sie können eine von TensorFlow.org herunterladen. Es handelt sich um ein generisches KI-Modell, das Sie in plattformübergreifenden Anwendungen wie iOS und Android verwenden können. Weitere Informationen zu Metadaten und zugeordneten Feldern (z. B. labels.txt) finden Sie unter Lesen der Metadaten aus Modellen.

  • Ein Objekterkennungsmodell wird trainiert, um das Vorhandensein und die Position mehrerer Klassen von Objekten zu erkennen. Ein Modell kann beispielsweise mit Bildern trainiert werden, die verschiedene Obststücke enthalten, zusammen mit einer Bezeichnung, die die Obstklasse angibt, die sie darstellen (z. B. Apfel), und Daten, die angeben, wo die einzelnen Objekte im Bild angezeigt werden.

    Wenn dem Modell ein Bild bereitgestellt wird, gibt es eine Liste der erkannten Objekte, die Position eines Begrenzungsrahmens für jedes Objekt und einen Score aus, der die Konfidenz der Erkennung angibt.

  • Wenn Sie ein KI-Modell erstellen oder optimieren möchten, lesen Sie TensorFlow Lite Model Maker.

  • Weitere kostenlose vortrainierte Erkennungsmodelle mit verschiedenen Latenz- und Genauigkeitsmerkmalen erhalten Sie im Detection Zoo. Jedes Modell verwendet die Eingabe- und Ausgabesignaturen, die in den folgenden Codebeispielen gezeigt werden.

ONNX

ONNX ist ein offenes Standardformat zur Darstellung von Machine Learning-Modellen. Es wird von einer Community von Partnern unterstützt, die es in vielen Frameworks und Tools implementiert haben.

  • ONNX unterstützt Tools zum Erstellen und Bereitstellen von Modellen und zum Ausführen anderer Aufgaben. Weitere Informationen finden Sie unter Unterstützte ONNX-Tools.
  • Sie können ONNX-Runtime verwenden, um vortrainierte ONNX-Modelle auszuführen. Informationen zu vortrainierten Modellen finden Sie unter ONNX Model Zoo.
  • Für dieses Szenario können Sie ein Modell zur Objekterkennung und Bildsegmentierung verwenden: Tiny YOLOv3.

Die ONNX-Community bietet Tools, mit denen Sie Ihr Deep Learning-Modell erstellen und bereitstellen können.

Herunterladen trainierter KI-Modelle

Zum Herunterladen trainierter KI-Modelle empfiehlt es sich, Gerätezwillinge zu verwenden, um Benachrichtigungen zu erhalten, wenn ein neues Modell bereit ist. Auch wenn das Gerät offline ist, kann die Nachricht in IoT Hub zwischengespeichert werden, bis das Edgegerät wieder online ist. Die Nachricht wird automatisch synchronisiert.

Es folgt ein Beispiel für Python-Code, der Benachrichtigungen für die Gerätezwillinge registriert und dann das KI-Modell in eine ZIP-Datei herunterlädt. Außerdem werden weitere Vorgänge für die heruntergeladene Datei ausgeführt.

Mit dem Code werden folgende Aufgaben ausgeführt:

  1. Erhalten von Benachrichtigungen der Gerätezwillinge. Die Benachrichtigung enthält den Dateinamen, die Download-Adresse der Datei und das MD5-Authentifizierungstoken. (Im Dateinamen können Sie Versionsinformationen wie 1.0 einschließen.)
  2. Herunterladen des KI-Modells als ZIP-Datei in den lokalen Speicher.
  3. Optionales Ausführen der MD5-Prüfsumme. Die MD5-Überprüfung hilft, ZIP-Dateien zu verhindern, die während der Netzwerkübertragung manipuliert wurden.
  4. Entpacken und lokales Speichern der ZIP-Datei.
  5. Senden einer Benachrichtigung an IoT Hub oder eine Routingnachricht, um zu melden, dass das neue KI-Modell bereit ist.
# 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"

            # TensorFlow flite
            # 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 )

Rückschluss

Nachdem das KI-Modell heruntergeladen wurde, ist der nächste Schritt die Verwendung des Modells auf dem Edgegerät. Sie können das Modell dynamisch laden und die Objekterkennung auf Edgegeräten durchführen. Im folgenden Codebeispiel wird veranschaulicht, wie Sie das TensorFlow Lite KI-Modell verwenden, um Objekte auf Edgegeräten zu erkennen.

Mit dem Code werden folgende Aufgaben ausgeführt:

  1. Dynamisches Laden des TensorFlow Lite KI-Modells.
  2. Durchführen der Bildstandardisierung.
  3. Erkennen von Objekten.
  4. Berechnen von Erkennungs-Scores.
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)

Im Folgenden ist die ONNX-Version des vorherigen Codes aufgeführt. Die Schritte sind größtenteils identisch. Der einzige Unterschied besteht darin, wie der Erkennungs-Score gehandhabt wird, da Labelmap und die Modellausgabeparameter unterschiedlich sind.

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)

Wenn Ihr IoT Edge-Gerät den vorherigen Code und die vorherigen Features enthält, verfügt Ihr Edgegerät über die Erkennung von KI-Bildobjekten und unterstützt die dynamische Aktualisierung von KI-Modellen. Wenn Sie möchten, dass das Edge-Modul anderen Anwendungen oder Modulen KI-Funktionalität über eine Web-API zur Verfügung stellt, können Sie in Ihrem Modul eine Web-API erstellen.

Flask-Framework ist ein Beispiel für ein Tool, mit dem Sie schnell eine API erstellen können. Sie können Bilder als Binärdaten empfangen, ein KI-Modell zur Erkennung verwenden und dann die Ergebnisse im JSON-Format zurückgeben. Weitere Informationen finden Sie unter Flask: Flask Tutorial in Visual Studio Code.

Beitragende

Dieser Artikel wird von Microsoft gepflegt. Er wurde ursprünglich von folgenden Mitwirkenden geschrieben:

Hauptautor:

  • Bo Wang | Senior Software Engineer

Andere Mitwirkende:

Melden Sie sich bei LinkedIn an, um nicht öffentliche LinkedIn-Profile anzuzeigen.

Nächste Schritte