KI in der Praxis: Fehlerhafte Bauteile mit Rekognition auf AWS identifizieren

Keine Kommentare

Noch vor kurzer Zeit mussten für den Einsatz von künstlicher Intelligenz (KI) unter großem Aufwand eigene KI-Modelle erstellt werden. Heute ist für viele Anwendungsfälle die Einstiegshürde in die Welt der KI durch Cloud-Computing-Dienste stark gesunken. So kann man viele Use Cases ohne Investment in KI-Forschung mittels bestehender KI-Technologie umsetzen. Ein Beispiel hierür ist die (Teil-)Automatisierung der Qualitätskontrolle von Bauteilen.

Warum es daher auch für kleine und mittelständischen Unternehmen spannend sein kann, sich mit KI zu beschäftigen, haben wir im Blogpost KI für KMU: (Teil-)Automatisierung der Qualitätskontrolle von Bauteilen beschrieben.

In diesem Artikel zeigen wir nun, wie ein solches Vorhaben exemplarisch auf AWS umgesetzt werden kann. Dazu trainieren wir mithilfe von Amazon Rekognition ein Modell und integrieren es mittels Lambda-Functions und Elastic Beanstalk perspektivisch in einen Prozess, der manuelle Nachkorrekturen in der Qualitätskontrolle erlaubt.

Der Code zu diesem Projekt befindet sich im Repository aws-automated-quality-inspection.

Architektur des KI-Systems

Die folgende Abbildung zeigt unsere Beispielarchitektur auf AWS.

Vogelperspektive der Implementierung auf AWS

Vogelperspektive der Implementierung auf AWS

Um ein KI-Modell zur Automatisierung zu erhalten, verwenden wir den Machine-Learning-Service Rekognition. Dieser ermöglicht es, ein State-of-the-Art-KI-Modell zur Bildklassifizierung auf einem eigenen Datensatz in wenigen Schritten zu trainieren. Darüber hinaus können die so trainierten Modelle direkt über den Service gehostet werden.

Da das Modell alleine noch keinen Mehrwert bietet, binden wir es exemplarisch in einen Prozess ein. Dabei werden Bilder von Bauteilen zunächst in einen S3-Bucket abgelegt. Der Upload eines Bildes triggert eine Lambda-Function, welche das gehostete KI-Modell aufruft und so das Bild klassifiziert. Das Ergebnis der Vorhersage wird dann zur weiteren Verarbeitung in eine SQS(Simple Queue Service)-Queue abgelegt.

Die SQS-Queue triggert eine zweite Lambda-Function. Diese enthält die Verarbeitungslogik, um eingehende Bilder anhand des Ergebnisses der Klassifikation zu sortieren. Vorhersagen, deren Konfidenz unter einem vorher definierten Schwellwert liegen, werden als „unsicher“ definiert. Solche Bilder müssen in einem weiteren Schritt durch Facharbeiter*innen nachbearbeitet werden. Diese Nachbearbeitung kann über eine auf Elastic Beanstalk gehostete Demo-Anwendung beispielhaft durchgeführt werden.

Um alle Komponenten dieses KI-Systems zum Laufen zu bringen, sind die folgenden drei Schritte notwendig:

  1. Vorbereitung, Training und Serving mit Rekognition
  2. Integration des Modells mit Lambda-Functions
  3. Deployment der Applikation zur manuellen Nachbearbeitung mit Elastic Beanstalk

Diese werden wir im weiteren Verlauf des Artikels genauer beschreiben.

Voraussetzungen

Für dieses Tutorial wird Zugang zu verschiedenen AWS-Services benötigt. Hierzu haben wir der Einfachheit halber ein AWS-Konto mit AdministratorAccess eingerichtet. In einer realen Produktionsumgebung sollte das „principle of least privilege“ erfüllt und das Konto oder ggf. die Konten entsprechend eingeschränkt werden. Zur Interaktion mit den AWS-Services verwenden wir die AWS CLI und setzen voraus, dass die nachfolgenden Umgebungsvariablen gesetzt sind oder die Befehle über ein entsprechendes AWS-Profil für die CLI ausgeführt werden.

AWS_ACCESS_KEY_ID="my-admin-account-access-key-id"
AWS_SECRET_ACCESS_KEY="my-admin-account-secret-access-key"
AWS_DEFAULT_REGION=eu-west-1 

Für unser Beispiel verwenden wir den Datensatz casting product data for quality inspection von Kaggle. Dieser beinhaltet Aufnahmen von Unterwasserpumpen-Bauteilen, die entweder als „okay“ oder „defect“ klassifiziert sind.

Der vollständige Code zum Projekt kann aus dem Repository aws-automated-quality-inspection heruntergeladen werden.

Vorbereitung, Training und Serving mit Amazon Rekognition

Nachdem die Daten von Kaggle heruntergeladen sind, werden diese entpackt und im data-Ordner gespeichert. Nach dem Entpacken hat das Verzeichnis die Struktur:

data
└── casting_data
    ├── test
    │   ├── def_front
    │   │   ├── ....
    │   │   └── new__0_9334.jpeg
    │   └── ok_front
    │       ├── ....
    │       └── cast_ok_0_9996.jpeg
    └── train
        ├── def_front
        │   ├── ...
        │   └── cast_def_0_9997.jpeg
        └── ok_front
            ├── ...
            └── cast_ok_0_9998.jpeg

Um ein KI-Modell mit Rekognition zu trainieren, müssen die Daten zunächst in einen S3-Bucket hochgeladen werden. Da Rekognition mit custom-labels derzeit in Europa nur in der Region EU-WEST-1 verfügbar ist, erstellen wir dort den Bucket und laden die Daten hoch.

TRAINING_DATA_BUCKET="product-quality-data"
aws s3 mb s3://${TRAINING_DATA_BUCKET}
aws s3 cp data/casting_data s3://${TRAINING_DATA_BUCKET}/ --recursive

Nun verwenden wir das Rekognition-UI, um den Service initial einzurichten. Dabei wird unter anderem ein zusätzlicher S3-Bucket erstellt, welchen Rekognition intern als Speicher verwendet.

Initiales Einrichten von Rekognition

Initiales Einrichten von Rekognition

Als nächstes erstellen wir ein Project in Rekognition, dieses dient insbesondere der Verwaltung zusammengehöriger Datensätze und Modelle.

Projekt erstellen in Rekognition

Projekt erstellen in Rekognition

Nun kann in Rekognition der Trainings- und Testdatensatz erstellt werden. Hierzu importieren wir die Daten aus dem vorher angelegten S3-Bucket und setzen die Label automatisch anhand der Ordnerstruktur.

Erstellen eines Datensatzes in Rekognition

Trainingsdatensatz in Rekognition erstellen

Um dem Rekognition-Service Zugang zu den Daten zu erlauben, muss die im UI angezeigte Permission für den TRAINING_DATA_BUCKET gesetzt werden.

Nach dem Import ist es möglich, die Daten in Rekognition zu inspizieren. Dies ist vor allem hilfreich, um die Datenqualität selektiv zu begutachten. Jetzt kann das Training des Modells gestartet werden. Hierzu wählen wir den vorher erstellten Training- und Testdatensatz aus.

Trainieren des Rekognition Models

Trainieren des Rekognition-Modells

Nach dem Training bekommt man eine erste Evaluation des Modells auf dem Testdatensazu direkt angezeigt. Hier kann man sich verschiedene Gütekriterien wie beispielsweise F1-Score anzeigen lassen. Weiterhin sind verschiedene Möglichkeiten gegeben, das Modell sowie dessen Vorhersagen interaktiv zu visualisieren.

Nun können wir das trainierte Modell als Service Endpoint starten.

aws rekognition start-project-version --project-version-arn "arn:aws:rekognition:eu-west-1:452161433274:project/product_quality/version/product_quality.2020-07-17T09.39.14/1594971554815" --min-inference-units 1 --region eu-west-1

Vorsicht: Ein laufendes Modell erzeugt Kosten von 4 Dollar pro Stunde.

Integration des Modells mit Lambda-Functions

Die Integration des Rekognition-Modells erfolgt über die zwei Lambda-Functions Prediction und Moving. Die Umsetzung ist im nachfolgenden Bild visualisiert.

Integration des Rekognition Modells mit Lambda-Functions

Integration des Rekognition-Modells mit Lambda-Functions

Für jeden Bild-Upload in den INBOUND_BUCKET wird die Prediction-Funktion automatisch ausgeführt. Die Funktion klassifiziert das Bild mit dem Rekognition-Modell-Endpoint. Anschließend schreibt sie das Ergebnis auf in eine SQS-Queue. Hierdurch wird wiederum die Moving-Funktion getriggert. Diese beinhaltet die Logik, um die Bilder anhand des Klassifizierungsergebnisses zu sortieren.

Vorbereitungen

Bevor wir die Lambda-Functions einsetzen können, müssen wir eine „executioner role“ mit entsprechenden Berechtigungen erstellen. In einer realen Produktionsumgebung sollten wir hier erneut das „principle of least privilege“ erfüllen. In dieser Demo halten wir es jedoch einfach und erstellen eine Rolle für beide Funktionen.

Zunächst erstellen wir die executioner role über:

aws iam create-role --role-name lambda-ex --assume-role-policy-document '{"Version": "2012-10-17","Statement": [{ "Effect": "Allow", "Principal": {"Service": "lambda.amazonaws.com"}, "Action": "sts:AssumeRole"}]}'

Anschließend fügen wir die Policies AWSLambdaFullAccess, AmazonSQSFullAccess and AmazonRekognitionCustomLabelsFullAccess hinzu:

aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/AWSLambdaFullAccess
aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/AmazonSQSFullAccess
aws iam attach-role-policy --role-name lambda-ex --policy-arn arn:aws:iam::aws:policy/AmazonRekognitionCustomLabelsFullAccess

Diese executioner-Rolle werden wir nun verwenden, um die Lambda-Functions zu deployen.

Prediction

Als Erstes werden die benötigten Umgebungsvariablen gesetzt:

ACCOUNT_ID="my-account-id"
MODEL_ARN="my-rekognition-mode-arn"
INBOUND_BUCKET="my_prediction_bucket"
PREDICTION_QUEUE="my_prediction_queue"
PREDICT_LAMBDA_NAME="predict_picture"

Hier ist die ACCOUNT_ID die ID des AWS-Kontos. Die MODEL_ARN ist die ARN des Rekognition-Modells, welches im vorherigen Schritt deployt wurde. Die ARN kann aus dem Rekognition-UI entnommen werden. Die Namen für den Bucket INBOUND_BUCKET und die SQS-Queue PREDICTION_QUEUE können frei gewählt werden. Der Wert für PREDICT_LAMBDA_NAME muss nicht geändert werden.

Dann erstellen wir den INBOUND_BUCKET und die PREDICTION_QUEUE.

aws s3 mb s3://${INBOUND_BUCKET}
SQS_QUEUE_URL=$(aws sqs create-queue --queue-name ${PREDICTION_QUEUE} --query "QueueUrl")

Hier speichern wir den Wert SQS_QUEUE_URL, da wir diesen in einem späteren Befehl benötigen. Als nächstes zippen wir den Code für die Lambda-Function mit:

cd lambda_functions/predict
zip predict_function.zip predict.py
cd ../..

Schließlich deployen wir über

aws lambda create-function \
--function-name ${PREDICT_LAMBDA_NAME} \
--zip-file fileb://lambda_functions/predict/predict_function.zip \
--runtime python3.7 \
--role arn:aws:iam::452161433274:role/lambda-ex \
--handler predict.lambda_handler \
--environment Variables="{model_arn=${MODEL_ARN},sqs_queue=${PREDICTION_QUEUE}}"

die Lambda-Function. Um die Lambda-Function bei jedem Upload eines Bildes in den INBOUND_BUCKET zu triggern, müssen wir als nächstes dem S3-Bucket die Erlaubnis erteilen, die Lambda-Function auszuführen.

aws lambda add-permission \
--function-name ${PREDICT_LAMBDA_NAME} \
--action lambda:InvokeFunction \
--statement-id s3invoke \
--principal s3.amazonaws.com \
--source-arn arn:aws:s3:::${INBOUND_BUCKET} \
--source-account ${ACCOUNT_ID}

Nun können wir die Event-Notification für den Bucket erstellen.

aws s3api put-bucket-notification-configuration \
 --bucket ${INBOUND_BUCKET} \
 --notification-configuration file://lambda_functions/s3triggerNotification.json

Hierzu muss die ARN der Lambda-Function im File s3triggerNotification.json angepasst werden.

Moving

Die Moving-Function verarbeitet Nachrichten auf der PREDICTION_QUEUE. Die Verarbeitungslogik ist im folgenden Bild dargestellt.

Verarbeitungslogik der Lambda-Function, die durch eine SQS-Queue getriggert wird.

Verarbeitungslogik der Lambda-Function, die durch eine SQS-Queue getriggert wird.

Sobald eine Nachricht eintrifft, löst das die Moving-Lambda-Function aus. Diese verarbeitet die Ergebnisse anhand der Konfidenz, dem Label und dem Schwellwert. Abhängig von diesen drei Werten wird das zugehörige Bild vom INBOUND_BUCKET in die spezifischen Verzeichnisse des PREDICTION_BUCKET bewegt:

  • okay: Bilder, auf denen kein Fehler erkannt wurde.
  • defect: Bilder, auf denen ein Fehler erkannt wurde.
  • unclear: Bilder, bei denen sich das Modell unsicher ist. In diesem Fall liegt die Konfidenz unter dem gewünschten Schwellwert.

Vor dem Deployment legen wir zunächst die folgenden Umgebungsvariablen an.

PREDICTION_BUCKET="my_prediction_bucket"
PREDICTION_THRESHOLD="0.8"
MOVE_LAMBDA_NAME="move_picture"

Hier kann der Name PREDICTION_BUCKET für den Bucket frei gewählt werden. Der PREDICTION_THRESHOLD definiert die Schwelle für Vorhersagen, die wir für unlcear halten. Der Name MOVE_LAMBDA_NAME muss nicht geändert werden.

Zunächst erstellen wir den S3-Bucket:

aws s3 mb s3://${PREDICTION_BUCKET}

Dann zippen wir den Code für die Lambda-Function

cd lambda_functions/move
zip move_function.zip move.py
cd ../..

und deployen sie mittels

aws lambda create-function \
--function-name ${MOVE_LAMBDA_NAME} \
--zip-file fileb://lambda_functions/move/move_function.zip \
--runtime python3.7 \
--role arn:aws:iam::452161433274:role/lambda-ex \
--handler move.lambda_handler \
--environment Variables="{prediction_bucket=${PREDICTION_BUCKET}, prediction_threshold=${PREDICTION_THRESHOLD}}"

Anschließend erstellen wir das Event-Source-Mapping, welches die Lambda-Functions über die SQS-Queue triggert

SQS_QUEUE_ARN=$(aws sqs get-queue-attributes --queue-url ${SQS_QUEUE_URL//\"} --attribute-names All --query Attributes.QueueArn)

aws lambda create-event-source-mapping \
 --function-name ${MOVE_LAMBDA_NAME} \
 --batch-size 1 \
 --event-source-arn ${SQS_QUEUE_ARN//\"}

Dabei benötigen wir den Wert SQS_QUEUE_URL von zuvor.

Deployment der Applikation zur manuellen Nachbearbeitung mit Elastic Beanstalk

Bei den unklaren Fällen wird der Input von Facharbeiter*innen benötigt. Über eine simple Webapplikation stellen wir hierfür die Bilder aus dem unclear-Verzeichnis des PREDICTION_BUCKET im Browser dar. Auf diese Weise können die Bauteile im Detail kontrolliert und manuell eingeteilt werden.

Die folgende Abbildung zeigt die Architektur der Applikation.

Architektur der Applikation mit Elastic Beanstalk, FastAPI, React und S3

Architektur der Applikation mit Elastic Beanstalk, FastAPI, React und S3

Die Applikation ist in Python mit FastAPI entwickelt und liefert mittels einer statischen Webseite ein React-Frontend aus.

Vorbereitungen

Um die Anwendung mit Elastic Beanstalk deployen zu können, verwenden wir die EB CLI.

Zuerst wechseln wir in das ebs_app/-Verzeichnis und initialisieren das Deployment über

eb init product-quality-api --platform python-3.7  --region eu-west-1  

Dadurch wird unter anderen der Ordner .elasticbeanstalk angelegt, in dem nun die Konfigurationsdatei config.yml der Anwendung liegt. Als nächstes erstellen wir die Laufzeitumgebung der Anwendung mittels

eb create product-quality-api-env --single     

Das --single-Flag baut die Umgebung mit einer einzigen EC2-Instanz und ohne Load Balancer, daher sollte diese Umgebung nur zum Testen etwa unserer Demo-Anwendung verwendet werden. Für produktive Anwendungen muss eine geeignete Konfiguration der Umgebung vorgenommen werden. Das Bereitstellen der Umgebung benötigt einige Minuten. Sobald die Umgebung erstellt ist deployen wir nun die Anwendung.

eb deploy product-quality-api-env  

Schließlich können wir die Anwendung über eb open im Browser öffnen:

Webanwendung um unsichere Bilder zu inspizieren – Bilder werden manuell als Ok oder Defect klassifiziert.

Webanwendung, um unsichere Bilder zu inspizieren – Bilder werden manuell als „Ok“ oder „Defect“ klassifiziert.

Die Applikation liest nun im PREDICTION_BUCKET das unclear-Verzeichnis aus. Um sie zu testen, kann ein Bild in das Verzeichnis hochgeladen werden. Nachdem das Bild manuell klassifiziert wurde, wird es im Verzeichnis human_decided mit dem Prefix des Labels abgespeichert.

Wie teuer ist der Betrieb dieses KI-Systems?

Eine Frage, die bei dem Betrieb einer solchen Cloud-Anwendung aufkommt, sind die Kosten. Grundsätzlich ist es schwierig, ohne konkreten Use Case eine genaue Kalkulation der Kosten aufzustellen. Neben der Anzahl an Aufrufen spielt auch noch das Umfeld der Lösung eine wichtige Rolle. Dennoch möchten wir an dieser Stelle auf die Kosten eingehen. Wir unterscheiden hierbei zwischen einmaligen, fixen und dynamischen Kostenpunkten:

  • Einmalig: Kosten beispielsweise für das Modelltraining
  • Fix: Kosten für die Verfügbarkeit der Anwendung. Zum Beispiel der Service Endpoint des Modells und Bereitstellung der Webanwendungen mit Elastic Beanstalk
  • Dynamisch: Kosten, die durch Benutzung und Auslastung anfallen, wie beispielweise Speicherplatz in S3 und Rechenzeit für Lambda-Functions.

Die folgende Tabelle listet die Haupt-Kostenpunkte des Systems ohne Bezug zum Netzwerk-Traffic:

Auflistung der Kosten ohne Netzwerktraffic
EinmaligFixDynamisch
Rekognition: Modell-Training 1 $ pro StundeRekognition: Modell-Deployment 4 $ pro StundeS3:
– Datenspeicherung: 0,023 $ pro GB (Erste 50 TB/Monat)
– Netzwerk (ausgehender Traffic): 0,09 $ pro GB (Bis 10,000 TB)
– Schreiben und Auflisten pro Objekt: 0,005 $ pro 1000 Vorgänge
– Lesen und Abrufen pro Objekt: 0,0004 $ pro 1000 Vorgänge
Elastic Beanstalk: t2.medium Instanz pro Stunde und Instanz 0,05 $Lambda Functions:
– Aufrufe: 0.20 $ pro 1M Aufrufe
– Rechenzeit bei 128 MB: 0.0000002083 $ pro 100ms

Um dennoch eine initiale Vorstellung der Kosten zu konkretisieren, gehen wir von der folgenden Annahmen aus:

  • Jeden Tag fallen 1.000 Bilder mit je 1 MiB an.
  • 5 % der Bilder werden als unsicher klassifiziert.
  • Die Anwendung läuft 24h am Tag über 30 Tage hinweg.

In diesem Kontext ergeben sich die nachfolgenden Kosten:

  • Einmalig:
    • Modell-Training: 1,08 $ * ~2 Stunden = 2,16 $
  • Fix:
    • Modell-Deployment: 4 $ * 24 Stunden * 30 Tage = 2880 $
    • Elastic-Beanstalk-Anwendung: 0,05 $ * 24 Stunden * 30 Tage = 36 $
  • Dynamisch:
    Die dynamischen Kosten fallen in unserem Beispiel nur marginal ins Gewicht, weshalb wir diese mit den folgenden Volumen abschätzen:

    • S3: < 1,5 $
    • Lambda-Functions: < 1 $

Hierbei berücksichtigen wir das Free Tier von AWS nicht.

Anhand dieser Rechnung ist klar erkennbar, dass das Modell-Deployment die höchsten Kosten verursacht. Diese Kosten können gegebenenfalls weiter reduziert werden, beispielsweise durch ein gezieltes Ein- und Ausschalten des Modells.

Fazit

In diesem Blog-Artikel haben wir gezeigt, wie man in wenigen Schritten ein initiales KI-System zur Semi-Automatisierung in der Qualitätskontrolle, auf AWS umsetzen kann.

Der Einsatz von Cloud-Computing-Diensten ermöglicht es, datengetriebene Services und Produkte einerseits schnell zu prototypisieren und andererseits mit überschaubarer Fertigungstiefe produktiv zu setzen. Insbesondere ermöglichen es Services wie Elastic Beanstalk und Lambda-Functions Entwickler*innen, sich mehr auf die eigentliche Wertschöpfung zu fokussieren und weniger mit dem operativen Betrieb der Anwendungen auseinanderzusetzen.

Zur Bilderkennung mittels KI kann heutzutage ein ausreichend gutes KI-Modell ohne mühsamen Aufwand entwickelt werden. Dadurch sinkt die Eintrittsbarriere zur Validierung datengetriebener Produkte. KI-Projekte können durch die technologischen Fortschritte in der Cloud-Entwicklung im Speedboot-Verfahren durchgeführt werden.

Unserer Herangehensweise an KI-Projekte haben wir in unserem On-Demand-Webinar (Deutsch) vorgestellt.

Jetzt einen unverbindlichen Austausch anfordern über ki@codecentic.de.

Marcel Mikl

Durch die mathematische Prägung im Zuge seiner Promotion ist es Marcel gewohnt, auftretende Probleme strukturiert zu lösen. Derzeit interessiert sich Marcel insbesondere für aktuelle Technologien rund um das Thema Data Science/Engineering und wie sich damit ein Mehrwert erzielen lässt.

Nico Axtmann

Als Machine Learning Engineer entwickelt Nico datengetriebene Produkte und Lösungen. Derzeit konzentriert er sich vor allem auf die Kombination von Natural Language Processing und Deep Learning.

Über 1.000 Abonnenten sind up to date!

Die neuesten Tipps, Tricks, Tools und Technologien. Jede Woche direkt in deine Inbox.

Kostenfrei anmelden und immer auf dem neuesten Stand bleiben!
(Keine Sorge, du kannst dich jederzeit abmelden.)

* Hiermit willige ich in die Erhebung und Verarbeitung der vorstehenden Daten für das Empfangen des monatlichen Newsletters der codecentric AG per E-Mail ein. Ihre Einwilligung können Sie per E-Mail an datenschutz@codecentric.de, in der Informations-E-Mail selbst per Link oder an die im Impressum genannten Kontaktdaten jederzeit widerrufen. Von der Datenschutzerklärung der codecentric AG habe ich Kenntnis genommen und bestätige dies mit Absendung des Formulars.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.