Upgrade to Pro — share decks privately, control downloads, hide ads and more …

【AWSハンズオン】サーバレスアーキテクチャで、有名人識別サービスを作ろう!

Hayate.H
October 25, 2020

 【AWSハンズオン】サーバレスアーキテクチャで、有名人識別サービスを作ろう!

・ソースコードはこちら → https://qiita.com/hayate_h/items/2091dda98bb07f758f06
・会社の同僚向けに、業務外にて行ったAWS勉強会の資料を公開したものです。
・AWS Lambda, Rekognition, API Gateway を用いて、有名人の画像識別サービスを作りましょう。
・基礎知識は必要ありません。
・AWS の IAM ユーザーアカウントが必要です。
・所要時間は約1時間です。

Hayate.H

October 25, 2020
Tweet

More Decks by Hayate.H

Other Decks in Programming

Transcript

  1. 本資料について • 会社の同僚向けに、業務外にて実施をした 「AWS ハンズオン」の資料を、一般公開したものです。 • サーバレスアーキテクチャを用いて、有名人の画像解析 API サービスを、 約1時間で作成するという内容になっています。

    • ハンズオンの実施にあたっては、以下のリソースや知識が必要です。 • インターネットに接続できるPC(Windows, Mac 問わない) • AWS IAM ユーザーアカウント • Pythonの知識 (基礎知識が無くても楽しめる構成にしています) • 本資料の作成には細心の注意を払っておりますが、 その正確性を担保するものではありません。 また、本資料が起因して生じた損害について、 作成者は一切の責任を負いません。
  2. 動作イメージ • ファイルを選択後、「送信」ボタンを押すと… • “He/She is Ken Watanabe with 100%

    confidence.” と表示されます。 • 今回のハンズオンでは、このサービスのバックエンドを作成していきます。
  3. アーキテクチャ説明 • クライアントPCから API Gateway 経由で有名人の画像をアップロード • 画像ファイルを受信すると、Lambda 関数が起動 •

    Lambda 関数内で Amazon Rekognition の recognize_celebrities 機能に 画像ファイルを送り、画像内の有名人を識別する • 取得した有名人の情報を出力用に整形して、API Gateway を通して返す • 呼び出し元のブラウザ上で、識別結果が表示される AWS Cloud AWS Lambda Amazon Rekognition Amazon API Gateway Client User 1 2 3 4 5 1 2 3 4 5
  4. AWSサービス紹介 • 今回使用する3つのサービスを簡単に紹介します。 • 「習うより慣れよ」の考えで、ハンズオンを進めていきましょう。 Amazon API Gateway ✓ フルマネージドなAPIサービス。

    ✓ 後述する「Lambda」などとつなげることで、 可用性の高いAPIを容易に開発できる。 ✓ サーバレスなコンピューティングサービス。 ✓ 実行したいコードを配置するだけで、 サーバなどの環境を意識することなくアプリを実行できる。 ✓ サーバレスな画像分析サービス。 ✓ 物体の判定、シーンの特定、テキスト検出、 人物の性別,年齢,感情推測などの多様な機能を提供している。 AWS Lambda Amazon Rekognition https://aws.amazon.com/jp/rekognition/?blog-cards.sort-by=item.additionalFields.createdDate&blog-cards.sort-order=desc
  5. 用語解説:「サーバレス」とは • 利用者がサーバを意識する必要のないサービスやアーキテクチャのこと。 → サーバが全く存在しないわけではない。サーバはAWSが管理している。 • プログラムコードを「置くだけ」で動作する。(運用管理が楽になる) 仮想サーバ コンテナ サーバレス

    Amazon EC2 AWS Lambda ロジック アプリ ランタイム OS 仮想化 ハードウェア ロジック アプリ ランタイム OS 仮想化 ハードウェア ロジック アプリ ランタイム OS 仮想化 ハードウェア ユーザー 管理 AWS 管理 自由度 運用管理 高 低 手間あり 楽 Amazon Elastic Container Service
  6. 用語解説:「マネージドサービス」とは • AWSが運用管理(の一部)を担ってくれるサービスのこと。 • 担ってくれる運用管理の内容や範囲はサービスによって多様だが、 「バックアップを定期的にとる」などだけではなく、 「アクセスが増えたら自動でスケールする」なども提供していることが多い。 • 運用管理の範囲が広く、利用者の手間がほとんどかからない場合は、 「フルマネージドサービス」と言われることが多い。

    • 「マネージド」であっても「サーバレス」ではないものもある。 マネージド ではないサービス マネージドだが、 サーバレスではない サービス マネージドかつ サーバレスな サービス Amazon EC2 ✓ 仮想サーバーサービス ✓ インスタンス単位で管 理をする ✓ 運用管理は利用者自身 で行う必要がある Amazon RDS ✓ データベースサービス ✓ インスタンスを意識す る必要はある ✓ バックアップやパッチ 適用などを自動化でき る(設定次第) ✓ AI翻訳サービス ✓ 大量アクセスにも対応 = インスタンスを意識 する必要がない ✓ 利用者は運用管理も全 く意識する必要がない Amazon Translate
  7. サインイン 補足情報 • 今回のハンズオンでは、 ハンズオンを実施するIAMユーザーに”AdministratorAccess”のIAMポリシーが 付与されていることを前提にして進めています。 • “AdministratorAccess” の権限が付与されていなかった場合、 以下の手順の中でリソースが作れない等のエラーが発生する可能性があります。

    • その場合は、システム管理者に問い合わせ、適切なポリシーをアタッチしても らうようにしてください。 • なお、以下のサイトに記載されていたIAMの設定内容は大変参考になりました。 (ハンズオンの手順が全て実行できることを確認済みです。) • 社外の開発メンバーをAWSアカウントに入れるときのIAM設定を考えている - kmiya_bbmのブログ https://kmiya-bbm.hatenablog.com/entry/2019/09/07/221740
  8. Lambda 関数の作成 def lambda_handler(event, context): a = 'Pen' b =

    'Pineapple' c = 'Apple' x = a + b + c + a return { 'statusCode': 200, 'body': x } • ソースコードは、以下のリンクからダウンロードをすることができます。 • 【AWSハンズオン】サーバレスアーキテクチャで、有名人識別サービス を作ろう! - Qiita • https://qiita.com/hayate_h/items/2091dda98bb07f758f06 • 今回記述したLambda 関数は以下の通りです。 • 変数に文字列を設定し、結合をしたものを return する内容となっています。 • 具体的には、 ’Pen’ + ’Pineapple’ + ’Apple’ + ’Pen’ → ‘PenPineappleApplePen’ になります。
  9. Lambda 関数の解説 • AWSマネジメントコンソールへアクセスし、 別途連絡をしたユーザー情報でサインインをしてください。 • https://console.aws.amazon.com/ import boto3 import

    base64 import logging import traceback logger = logging.getLogger() logger.setLevel(logging.INFO) rekognition = boto3.client('rekognition') def lambda_handler(event, context): logger.info(f'Received event = {event}') received_body = base64.b64decode(event['body-json']) images = received_body.split(b'¥r¥n',4) image = images[4] response = rekognition.recognize_celebrities( Image={'Bytes': image} ) logger.info(f'Rekognition response = {response}') try: label = response['CelebrityFaces'][0] name = label['Name'] conf = round(label['Face']['Confidence']) output = f'He/She is {name} with {conf}% confidence.' logger.info(f'API response = {output}') return output except IndexError as e: logger.info(f"Coudn't detect celebrities in the Photo. Exception = {e}") logger.info(traceback.format_exc()) return "Couldn't detect celebrities in the uploaded photo. Please upload another photo." • 必要なモジュールのインポートをし ています。 • boto3はPythonでAWSリソースを操作 する際に用いるSDKです • https://boto3.amazonaws.com/v1/doc umentation/api/latest/reference/servi ces/index.html
  10. Lambda 関数の解説 • AWSマネジメントコンソールへアクセスし、 別途連絡をしたユーザー情報でサインインをしてください。 • https://console.aws.amazon.com/ import boto3 import

    base64 import logging import traceback logger = logging.getLogger() logger.setLevel(logging.INFO) rekognition = boto3.client('rekognition') def lambda_handler(event, context): logger.info(f'Received event = {event}') received_body = base64.b64decode(event['body-json']) images = received_body.split(b'¥r¥n',4) image = images[4] response = rekognition.recognize_celebrities( Image={'Bytes': image} ) logger.info(f'Rekognition response = {response}') try: label = response['CelebrityFaces'][0] name = label['Name'] conf = round(label['Face']['Confidence']) output = f'He/She is {name} with {conf}% confidence.' logger.info(f'API response = {output}') return output except IndexError as e: logger.info(f"Coudn't detect celebrities in the Photo. Exception = {e}") logger.info(traceback.format_exc()) return "Couldn't detect celebrities in the uploaded photo. Please upload another photo." • Logger を INFO レベルで設定します。 • デバッグ用途に使用しています。
  11. Lambda 関数の解説 • AWSマネジメントコンソールへアクセスし、 別途連絡をしたユーザー情報でサインインをしてください。 • https://console.aws.amazon.com/ import boto3 import

    base64 import logging import traceback logger = logging.getLogger() logger.setLevel(logging.INFO) rekognition = boto3.client('rekognition') def lambda_handler(event, context): logger.info(f'Received event = {event}') received_body = base64.b64decode(event['body-json']) images = received_body.split(b'¥r¥n',4) image = images[4] response = rekognition.recognize_celebrities( Image={'Bytes': image} ) logger.info(f'Rekognition response = {response}') try: label = response['CelebrityFaces'][0] name = label['Name'] conf = round(label['Face']['Confidence']) output = f'He/She is {name} with {conf}% confidence.' logger.info(f'API response = {output}') return output except IndexError as e: logger.info(f"Coudn't detect celebrities in the Photo. Exception = {e}") logger.info(traceback.format_exc()) return "Couldn't detect celebrities in the uploaded photo. Please upload another photo." • boto3 から、recognition を呼び出す インスタンスを生成しています。
  12. Lambda 関数の解説 • AWSマネジメントコンソールへアクセスし、 別途連絡をしたユーザー情報でサインインをしてください。 • https://console.aws.amazon.com/ import boto3 import

    base64 import logging import traceback logger = logging.getLogger() logger.setLevel(logging.INFO) rekognition = boto3.client('rekognition') def lambda_handler(event, context): logger.info(f'Received event = {event}') received_body = base64.b64decode(event['body-json']) images = received_body.split(b'¥r¥n',4) image = images[4] response = rekognition.recognize_celebrities( Image={'Bytes': image} ) logger.info(f'Rekognition response = {response}') try: label = response['CelebrityFaces'][0] name = label['Name'] conf = round(label['Face']['Confidence']) output = f'He/She is {name} with {conf}% confidence.' logger.info(f'API response = {output}') return output except IndexError as e: logger.info(f"Coudn't detect celebrities in the Photo. Exception = {e}") logger.info(traceback.format_exc()) return "Couldn't detect celebrities in the uploaded photo. Please upload another photo." • この Lambda_handler 関数が、 APIコールがあった際に起動される関 数となります。
  13. Lambda 関数の解説 • AWSマネジメントコンソールへアクセスし、 別途連絡をしたユーザー情報でサインインをしてください。 • https://console.aws.amazon.com/ import boto3 import

    base64 import logging import traceback logger = logging.getLogger() logger.setLevel(logging.INFO) rekognition = boto3.client('rekognition') def lambda_handler(event, context): logger.info(f'Received event = {event}') received_body = base64.b64decode(event['body-json']) images = received_body.split(b'¥r¥n',4) image = images[4] response = rekognition.recognize_celebrities( Image={'Bytes': image} ) logger.info(f'Rekognition response = {response}') try: label = response['CelebrityFaces'][0] name = label['Name'] conf = round(label['Face']['Confidence']) output = f'He/She is {name} with {conf}% confidence.' logger.info(f'API response = {output}') return output except IndexError as e: logger.info(f"Coudn't detect celebrities in the Photo. Exception = {e}") logger.info(traceback.format_exc()) return "Couldn't detect celebrities in the uploaded photo. Please upload another photo." • rekognitionの使い方は、boto3のド キュメントに記載されています。 • https://boto3.amazonaws.com/v1/doc umentation/api/latest/reference/servi ces/rekognition.html#Rekognition.Clie nt.recognize_celebrities
  14. Lambda 関数の解説 • AWSマネジメントコンソールへアクセスし、 別途連絡をしたユーザー情報でサインインをしてください。 • https://console.aws.amazon.com/ import boto3 import

    base64 import logging import traceback logger = logging.getLogger() logger.setLevel(logging.INFO) rekognition = boto3.client('rekognition') def lambda_handler(event, context): logger.info(f'Received event = {event}') received_body = base64.b64decode(event['body-json']) images = received_body.split(b'¥r¥n',4) image = images[4] response = rekognition.recognize_celebrities( Image={'Bytes': image} ) logger.info(f'Rekognition response = {response}') try: label = response['CelebrityFaces'][0] name = label['Name'] conf = round(label['Face']['Confidence']) output = f'He/She is {name} with {conf}% confidence.' logger.info(f'API response = {output}') return output except IndexError as e: logger.info(f"Coudn't detect celebrities in the Photo. Exception = {e}") logger.info(traceback.format_exc()) return "Couldn't detect celebrities in the uploaded photo. Please upload another photo." • これは、実はアンチパターンの return 文です。 • 実際には、Lambdaのプロキシ統合の フォーマットに合わせたレスポンス 形式にすると良いでしょう。 • 今回は、ブラウザ上での動作確認を 行うため、明示的にプロキシ統合を 使わず、また出力のフォーマットも 意図的に無視をした記載にしていま す。 • 詳しくは「API Gateway 統合レスポン ス」で検索してください。 • https://docs.aws.amazon.com/ja_jp/ap igateway/latest/developerguide/api- gateway-integration-settings- integration-response.html
  15. API Gateway の追加 • ここから、API Gateway と Lambda を紐づけていきます。 AWS

    Cloud AWS Lambda Amazon Rekognition Amazon API Gateway Client User
  16. API Gateway の追加 • API は「リソース」×「メソッド」で開発をしていきます。 • 例えば「/users に GET」や「/users/12345

    にPOST」などです。 リソース メソッド アクション /users/12345 /users/12345 GET POST userid=12345 の ユーザー情報を取得 userid=12345 で ユーザー情報を新規登録 /users/12345 PUT userid=12345 で ユーザー情報を更新 (新規登録の場合もあり) /users/12345 DELETE userid=12345 で ユーザー情報を削除 /users GET 全てのユーザー情報を 取得
  17. HTMLファイルの作成 • 以下のHTMLの****API Gateway URL 貼り付け****の部分に、先ほど作成し たAPI Gateway の URLを貼り付け、"index.html"のファイル名で保存します。

    • ソースコードは以下のリンクからダウンロードをしてください。 • https://qiita.com/hayate_h/items/2091dda98bb07f758f06
  18. HTMLファイルの解説 • フォームを用いて、選択されたファイルを送信するだけの、 単純な HTML 構文です。 <!DOCTYPE html> <html lang="ja">

    <head> <meta charset="UTF-8"> <title>有名人認識AIハンズオン</title> </head> <body> <p>画像識別AIである Amazon Rekognition を用いて、 有名人の認識をします!</p> <form action="****API Gateway URL 貼り付け****" enctype="multipart/form-data“ method="POST"> <input type="file" name="写真ファイルを選択" /> <input type="submit" name="アップロード"/> </form> </body> </html> • ここに、作成したAPI Gateway の URLを入力します。
  19. 動作確認 • ファイルを選択し、「送信」ボタンを押すと… • "He/She is Ken Watabe with 100%

    confidence." • と表示されました!識別サービス完成です! さすが「世界のワタベ」ですね。
  20. お片付け • 以下のリソースを削除していきます。 • API Gateway • Lambda • CloudWatch

    ロググループ(Lambda の実行ログ) • Lambda用 IAMロール AWS Cloud AWS Lambda Amazon Rekognition Amazon API Gateway Client User IAM Role Amazon CloudWatch Logs
  21. 料金 • AWSの各種サービスには、一定の無料利用枠があります。 • 今回の構成は、APIを大量にコールしない限り、 全てAWSの無料利用枠に収まる想定です。 • 参考までに、無料枠を超えた際に発生する料金の目安を記載しておきます。 (2020年10月13日時点 東京リージョン

    月単位) サービス分類 区分 料金 補足 データ通信料 AWSへのイン 0.000USD/GB AWSからのアウト 0.114USD/GB 最初の1GB~10TB CloudWatch ログ収集 0.760USD/GB ログ保存 0.033USD/GB Lambda リクエスト課金 0.20USD/100万件 実行時間課金 0.0000002083USD /128MB,100ミリ秒 API Gateway REST API 4.25USD/100万件 最初の3 億3,300万 コール受信数 Rekognition Image 0.0013USD/1画像 最初の100万枚
  22. 参考資料・ドキュメント • AWS Hands-on for Beginners Serverless #1 サーバーレスアーキテクチャで翻訳 Web

    API を構築する| AWS • https://pages.awscloud.com/event_JAPAN_Hands-on-for-Beginners- Serverless-2019_LP.html • AWS API Gateway + Lambda から multipart/form-dataを用いて バイナリデータ(wav)をS3にputする – Qiita • https://qiita.com/tetsu0831/items/220ba032116dc94063b3 • Rekognition — Boto3 Docs 1.15.11 documentation • https://boto3.amazonaws.com/v1/documentation/api/latest/reference/servic es/rekognition.html • API Gateway で統合レスポンスを設定する - Amazon API Gateway • https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api- gateway-integration-settings-integration-response.html • その他、AWS 公式ドキュメント
  23. EOF