Technology Topics by Brains

ブレインズテクノロジーの研究開発機関「未来工場」で働くエンジニアが、先端オープン技術、機械学習×データ分析(異常検知、予兆検知)に関する取組みをご紹介します。

AWS re:Invent 2019 Session - Building machine-learning infrastructure on Amazon EKS with Kubeflow

Impulseの開発をしている樋口です。

今回は表題のセッションについて少しまとめます。

モチベーション

セッションはEKSで機械学習基盤を構築するという題目でしたが、AWSにはAmazon SageMakerというEnd to Endの機械学習サービスがあります。 aws.amazon.com

なぜSageMakerを使わずにEKSを利用して個別に機械学習のインフラを作り上げるのか(しかも今回のre:Inventで相当のアップデートが発表されました)、理由は以下が紹介されていました。

  • Portability
  • Composability
  • Scalability

以下そのうち2つを詳しく書いておきます。(ScalabilityはSageMakerでも,,,というところはあるので)

Portability

オンプレミス環境でもプロダクトを動作させる事が求められる場合、クラウドサービスにロックインした形で実装を進めてしまうと、クラウドサービスが担っていてくれた部分を一部自分で実現しなくてはならなく、 同じロジックを違う手段で実装し直すということが発生する。 クラウド・オンプレミス両方で同じ手段を使い動作する事で最小限の手間でプロダクトをポータブルにすることができる。

Composability

現在Kubernetes界隈にはたくさんのOSSがあり、それらを組み合わせることにより様々な機能を実現することができる。コンテナ基盤として使えるので、追加の個別の要件にも対応しやすい。

機械学習基盤

機械学習基盤として、満たすべき要件は

  • Authentication/Authorizationのサポート
  • Notebookを使ったデータ分析者による分析
  • パイプラインの実行
  • 並列分散処理によるモデル構築
  • スケーラブルな推論
  • メトリクスの可視化
  • インフラレイヤーの抽象化

など多々ありますが、これらを満たすために手段としてkubeflowが紹介されていました。 f:id:mhigu:20191204123205j:plain www.kubeflow.org kubeflowの各機能詳細については、公式ドキュメントを参照してもらうとして確かにこれだけでも機械学習基盤として必要な要件は最低限満たせるかもしれません。

kubeflowのパイプラインではTensorFlow, scikit-learn, PyTorchのいずれの処理でもパイプラインの一つの要素として定義することができます。 f:id:mhigu:20191205022107j:plain

一つのライブラリに依存せず基盤を準備できるのは便利( ゚∀゚)・∵. グハッ!!

まぁ、kubeflowの裏ではargoというもっと抽象的なworkflow engineが動いているので、何でも実行できるのは不思議では無いですね。 github.com

また、kubeflowと一緒にhorovodというライブラリが紹介されていました。 github.com 一応スピーカいわく現在一番洗練された分散学習のフレームワークの一つらしいです。

事例

実際にEKSをベースにして、この様な基盤を組んだ企業の事例紹介がありました。

基本的には上記で紹介したkubeflowをベースに以下の様な構成で、 f:id:mhigu:20191204125352j:plain

追加でPrometheus/Grafanaを導入して以下項目の可視化も行っていたとのことでした。

  • cpu
  • memory
  • cluster state
  • job metrics
  • cost f:id:mhigu:20191204130206j:plain コストが見えてるのいいですね。

また、この企業ではEKSベースの機械学習基盤をグローバルに展開しており、それをどこからでも利用できるようにするために複数の機械学習基盤をまとめるREST APIを作ってユーザーにはREST API経由で実際のジョブの実行をさせる様にしていました。

f:id:mhigu:20191204130439j:plain

こうすることで複数の基盤をまとめる事ができたのに加えて、ユーザーが指定しなければならない項目をシンプルにできたとも言っていました。 (kubernetesの利用障壁に煩雑なyamlを書く作業があるが、REST APIにすることでその部分を隠蔽できる。wall of YAML 突破か,,,(ヾノ・∀・`)ムリムリ)

所感

このセッションを通じて話されていた事は弊社のプロダクトにも共通の部分が多くあり、実際に同じようなものを動かしている人の話を聞くとやる気が上がりますね。 見聞きした事は、今後またImpulseの開発に生かしていきます。

AWS re:Invent 2019 に行く

AWS re:Invent 2019

Impulseの開発をしている樋口です。

12/2(月) - 12/6(金)の間で開催されているAWS re:Inventに参加しています。 セッションでの興味深かった内容はまた別途書くとして、まずは雰囲気をお伝えします。

Las Vegas

こんな感じのホテルがあちこちに。 f:id:mhigu:20191203093453j:plain

とにかく中がひろいでかい豪華。 f:id:mhigu:20191203093542j:plain

自分たちの泊まったホテルはFlamingo Las Vegasというホテルですが、 goo.gl その中庭にはフラミンゴが。 f:id:mhigu:20191203093505j:plain

あと、写真は撮れないので無いですが、そこら中にカジノがあり自分はベガス到着から2日で$300ブラックジャックで失いました。。。 安いApple Watchが買える値段。ご利用は計画的に_| ̄|○ il||li

AWS re:Invent

会場

セッション前日から会場は人で賑わっていて、各々壁に落書きしたりビリヤードしたりとくつろいでいます。 f:id:mhigu:20191203100527j:plain サインアップを済ませるとSWAGがもらえます。今回もパーカーとウォーターボトル。 f:id:mhigu:20191203094751j:plain f:id:mhigu:20191203095209j:plain 他にもノベルティが至るところでもらえるようなので、お土産としてたくさん確保していきます。

セッション

因みにセッションの確保競争は年々盛り上がっているようで、殆どのセッションが予約開始日から埋まります。 写真の青いのが興味のあるセッションですが、全て埋まっていて取れません。 f:id:mhigu:20191203094755p:plain 一応当日枠もあるので、泥臭く並んで空いてたら入ろうと思います。

まとめ

  • まずはアメリカの規模を実感する
  • カジノは適度に楽しみましょう
  • セッション確保は仁義なき戦い

以上です。

JAWS-UGでAmazon re:MARSの参加報告をして来ました

こんにちは,ブレインズテクノロジー / 未来ラボの奥山です.

先週の7/19に,AWSの東京ユーザーグループ(#jawsug_tokyo)で,Amazon re:MARSの参加報告をする機会をいただきました.

re:MARSは,去る6/4-7にLas Vegasで開催されたAmazon.com主催のイベントで,機械学習・ロボットから宇宙まで幅広いトピックに触れられる会議です. 弊社でも,わたしを含む4名が参加し,いろいろな学びを得て帰って来ました.

f:id:brains-tech:20190724150438j:plain

f:id:brains-tech:20190723130508j:plain
re:MARS会場のAria Resort

個人的には,Amazon CEOのJeff Bezos氏やCourseraでお世話になったAndrew Ng先生(それからアイアンマンことRobert Downy Jr.氏も)の講演を生で聞くことが出来て,感動ひとしおでした.

さて今回のユーザーグループでのrecapは,学んだことを整理するとても良い機会になりました. 特に心に残った講演者のキーメッセージを引用させていただきつつ,振り返りを記事にまとめました.

f:id:brains-tech:20190723110107j:plain
JAWSUGでの発表の様子(写真はtwitterから拝借しました).みなさん本当にプレゼン上手ですね…精進します.

続きを読む

GreengrassをDocker for Windows上で使用する準備とファイル読み出しテストの手順

こんにちは、ブレインズテクノロジーの岩城です。

2018年11月末に開催されたAWS re:Invent2018で、AWS Greengrass IoTをDockerコンテナ上で起動できるようになったことが発表されました。

aws.amazon.com

この機能を生かしたデータ活用手法について、先日公開した「Dockerコンテナ上で起動したGreengrassとWindowsとの連携で広がる新たなデータ活用の選択肢」という記事でご紹介しました。

本記事では少し技術的な内容に踏み込み、GreengrassをDocker for Windows上で使用するための準備の手順と、チュートリアルを拡張して実施したGreengrassからWindows上のファイル読み込みトライアルをご紹介します。

技術ではなく応用例に関心がある場合は、下記の記事をご参照ください。 blog.brains-tech.co.jp

環境について

使用する環境としては、前回の記事でも紹介した三菱電機製の産業用PC MELIPC1002-Wを使用します。MELIPCは生産設備などから集めたデータを集約・加工する機能と、集めてきたデータを活用するためのインターフェースを備えた産業用途のPCです。MELIPCについての詳細は前回の記事やこちらの製品ページなどご参照ください。 http://www.mitsubishielectric.co.jp/fa/products/edge/melipc/items/mi1000/index.html

今回の取り組みでは、MELIPC上のWindows10にDocker for Windowsをインストールし、このDocker環境でGreengrassを動作させます。

使用したWindowsのスペックについては下記の画像をご覧ください。

f:id:brains_iwaki:20190124184333p:plain

読み込みの対象とするcsvファイルはこちらで準備したダミーのファイル (sample_data1.csv, sample_data2.csv)を使用しています。

実施概要

今回実施した内容は、Docker for Windows上でGreengrassを実行し、ローカル環境にあるcsvファイルを読み込ませてクラウドに送信させるというものです。

基本的な流れはAWSが提供している下記のリンクのチュートリアル通りですが、先々の応用を考え、一部変更を加えています。

docs.aws.amazon.com

大きな変更点は、下記の3点です。

  1. Hello Worldの代わりに、ローカル環境にあるcsvファイルを読みとるLambda関数を用意する。
  2. ローカル環境にcsvファイルを準備しておく。
  3. Dockerコンテナを起動する際に、マウントするホストの情報をコマンドに追加しておく。

今回は出荷状態のMELIPCを使用したので、Dockerのインストールやコマンドのインストールなども一から実施しています。
ユーザーを作成する部分などはさすがに割愛しますが、Greengrassを動かす前の事前準備から一通り行った作業を記載していきます。

Dockerコンテナ上でGreengrassを使用するための下準備

まずは、Dockerコンテナ上でGreengrassを使用できるように環境を整えていきます。

事前準備の概要

今回の一連のトライアル実施のため、まずはチュートリアルの指示通り、下記のソフトウェアをインストールしました(括弧内はバージョン)。

  • Docker (18.09)
  • Python (3.7) (※3.6以上ならOK)
  • pip (18.1)
  • AWS CLI (1.16)

その他、さらに前提として、AWSのアカウントを所有している必要があるので、持っていない場合は事前に作成しておきましょう。

Dockerのインストール

まずはDockerをインストールします。

チュートリアルの中のDockerへのリンクを開き、Docker Community Edition (CE)をダウンロードします。

docs.docker.com

今回はWindowsなので、スクロールしてDocker Desktop for Windows (Microsoft Windows 10)のリンクに飛びます。

(参考)
https://docs.docker.com/docker-for-windows/install/

f:id:brains_iwaki:20190124183815p:plain
Docker for WIndowsのインストールページ

Install Docker Desktop for Windows desktop appの中からDocker Desktop Installer.exeをダウンロードし、実行した後は、ウィザードに従ってインストールを進めていきます。

途中でDocker ToolboxかDocker for Windowsを選択する箇所があります。今回の用途ではDocker for Windowsを選択します。
但し、Docker for Windowsを使用する場合はVirtualBoxが起動できなくなるので注意してください(後述)。

インストール後は一度再起動し、Docker for Windowsのdesktop appを開きます。
この際、有効化が必要等のメッセージが出た場合は、メッセージを読み、問題なさそうであればOKを押して進めていきます。

以上でDockerのインストールは完了…と思ったのですが改めて起動したところ、“Not enough memory to start Docker Desktop”というメッセージが出ました。
これはDocker DesktopのsettingsからMemoryの値を下げることで解決できました。

(参考)
https://qiita.com/chakimar/items/868298096ebf9186d690

最終的な設定はこちらの画像のようになります。

f:id:brains_iwaki:20190124183933p:plain
最終的なDockerのsettingsの内容

再起動などをした時などにDockerがどのような状態になっているかは、右下のステータスバーから確認できます。

f:id:brains_iwaki:20190124184041p:plain

ここの白い鯨のアイコンが上記の画像の状態で停止していれば起動している状態です。

なお、一つ前に記載した設定画面は、このアイコンを右クリックしてsettingsを選んだ画面から開きます。

完全に起動ができたら、最後に、コマンドプロンプトで

docker version

などのコマンドを実行すると正しくdockerがインストールできているかの確認ができます。

Docker Desktop for Windowsのインストールにおける注意点

インストールページに記載されているように、Docker Desktop for Windowsインストールの際は下記の点に注意が必要です。

(1)Docker ToolboxとDocker Machineユーザー向けの注意点

Docker Desktop for Windowsでは、Microsoft Hyper-Vを使用します。 そのため、Hyper-Vが使用可能になっている必要があるのですが、Hyper-Vが使用可能な状態の場合は、VirtualBoxが使用できなくなります。 Hyper-VとVirtualBoxを並行して利用することができないので、注意しましょう。
なお、Hyper-Vの設定変更はインストーラーの方で行なってくれます。

(2)システム要件

こちらもインストールページに記載がある通りです。本記事の執筆時点では、下記のような条件があります。

  • Windows 10 64bit: Pro, Enterprise or Education
  • BIOSのVirtualizationがenableになっていること ( Hyper-Vとは別の話。基本的にenableらしい)
  • CPUがSLAT-capableであること
  • 最低4GBのRAM

今回使用したMELPICに搭載されているWindowsOSは、

  • Windows 10 Enterprise
  • 実装RAM: 4GB
  • システムの種類: 64ビット オペレーティングシステム、x64ベースプロセッサ

となっていたので、この辺りの条件はクリアできていたようです。

参考までに、今回使用したMELIPC M1002-W上のWindows上のスペックを再掲します。 f:id:brains_iwaki:20190124184333p:plain

Pythonのインストール

次に、Pythonの公式サイトからWindows用のPython3.6以上のインストールを行います。

https://www.python.org/downloads/windows/

種類がいくつもありますが、今回はx86-64 executable installerを選択しました。
簡単に補足すると、x86-64は64ビット版 (x86は32ビット版)、 executable installerはインストールに必要な要素を全てまとめてexeファイル内で保持しているようなインストールファイルです。

(参考)
https://stackoverflow.com/questions/38651672/difference-between-web-based-and-executable-installers-for-python-3-on-windows
https://python-forum.io/Thread-Python-3-x86-vs-x64-Inquiry

pipのインストール

pipは上記インストールに標準で入っていました。

updateが必要なので、下記のコマンドプロンプトで下記のコマンドを実行しました。

python -m pip install —-upgrade pip

ここは少々記憶が怪しいのですが、確か普通にpip install —upgrade pipを行うと上手くいかなかったように思います。 エラーメッセージでこのコマンドを提示してくれたかもしれないので、一度試してみて、駄目そうなら使ってみてください。

(参考)
https://qiita.com/icoxfog417/items/278ea9e217ac6fb7f10b

AWS CLIのインストール

AWS CLIのインストールは下記のコマンドです。

pip install awscli --upgrade —user

(参考)
https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-install.html

また、AWS CLIがコマンドプロンプトから実行できるようにパスの追記などを行う必要があります。 この辺りは下記のリンクを参照してください。

https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/install-windows.html#awscli-install-windows-path

Greengrass in Docker Containerの実行とファイル読み込みテスト

ここまででようやく下準備が終わりました。 次に、GreengrassをDocker for Windows上で起動し、テストを行います。
改めて、チュートリアルへのリンクを掲載しておきます。

docs.aws.amazon.com

作業としては、

  1. Greengrassを動作させるコンテナのイメージの取得
  2. Greengrassコアとグループの準備 (+Lambda関数の準備)
  3. AWS IoT Greengrassをローカルで起動 (コンテナを立ち上げる)
  4. Greengrassコア側の設定
  5. デプロイ
  6. AWS IoTを使用してのテスト

という流れになります。

1. コンテナイメージのプル

AWSでAWS IoT Greengrassの依存関係などの設定が完了済みのイメージが提供されているので、今回はそれを利用します。

チュートリアル通り、下記のコマンドを順に実行していきます。

(1)ログインコマンドの取得 まずは下記のコマンドを実行します。このコマンドを使うことで、出力としてDockerクライアントの認証に必要なログインコマンドを取得することができます。

aws ecr get-login --registry-ids 216483018798 --no-include-email --region us-west-2

configurationの設定ができていない場合はここでCredential Errorが発生することがあるので、その際は下記のリンクなどを参考に解決してください。
https://docs.aws.amazon.com/ja_jp/cli/latest/userguide/cli-configure-envvars.html

(2) (1)で出力されたコマンドをそのままコピーして実行します。

(3)下記コマンドでコンテナイメージを取得します。

docker pull 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-greengrass-docker/amazonlinux:latest

あるいは、FAQの方でイメージを直接ダウンロードできるリンクが掲載されていたので、こちらをダウンロードして、docker loadコマンドでimageを取り込む形も取れるでしょうか。

https://aws.amazon.com/jp/greengrass/faqs/

興味のある方は上記リンク内で、 “Docker コンテナで AWS IoT Greengrass を実行できますか?”という文言で検索してみてください。

2. Greengrassのグループとコアを作成 + Lambda関数の準備

まずは通常のGreengrassのグループおよびコアを作成する作業を行います。

これについては、基本的なGreengrassのチュートリアル通りに進める流れになります。

AWS IoT の AWS IoT Greengrass の設定

この作業が初めての方は、一旦ここは後回しにして、通常のGreengrassのチュートリアルを行うところから始めるのが良いかと思います。

作業の途中でダウンロードする証明書情報と設定ファイルは後ほど使用するので保存しておきます。
また、チュートリアルにも記載がありますが、AWS IoT Greengrassコアソフトウェアは今回使用しているイメージに準備されているので、ダウンロードする必要はありません。

次に、Lambda関数の準備もここで実施しておきます。

今回使用したLambda関数のコードはこちらです。

import greengrasssdk
import platform
import os


client = greengrasssdk.client('iot-data')
my_platform = platform.platform()

TARGET_TOPIC = os.getenv("TARGET_TOPIC", "hello/world")
RETURN_MESSAGE = os.getenv("RETURN_MESSAGE", "Hello world! Sent from Greengrass Core.")
TARGET_DIR_PATH = os.getenv("TARGET_DIR_PATH", "/tmp")

def greengrass_hello_world_run():
    if not my_platform:
        client.publish(topic=TARGET_TOPIC, payload=RETURN_MESSAGE)
    else:
        client.publish(topic=TARGET_TOPIC, payload= RETURN_MESSAGE + ' Running on platform: {}'.format(my_platform))
    if os.path.isdir(TARGET_DIR_PATH):
        file_list = [os.path.join(TARGET_DIR_PATH, item) for item in os.listdir(TARGET_DIR_PATH) if (item.endswith(".csv")) and (item.startswith(".") == False)]
        file_list.sort()
        if len(file_list) > 0:
            for use_file in file_list:
                with open(use_file, "r") as f:
                    first_row = f.readline()
                first_row = str(first_row)
                main_filename = use_file.split("/")[-1]
                client.publish(topic=TARGET_TOPIC, payload="File name is {}".format(main_filename))                
                client.publish(topic=TARGET_TOPIC, payload="First row of this file: {}".format(first_row))
        else:
            client.publish(topic=TARGET_TOPIC, payload="There is no csv file")
    else:
        client.publish(topic=TARGET_TOPIC, payload="The TARGET_DIR_PATH dose not exist.")

def function_handler(event, context):
    greengrass_hello_world_run()
    return

この関数では、環境変数としてファイルの読み込み先のパスやトピックの発行先、ベースになるメッセージの内容を指定できるようにしています。

関数の中でgreengrasssdkなどを使っているので、ライブラリも忘れずにアップロードしてください。 チュートリアルで提供されているHelloWorld.pyを改修すると早いかもしれません。

handlerの設定などについては、下記の画像を参考にしてください。

f:id:brains_iwaki:20190124191402p:plain

これを通常のLambda関数のアップロードの手順に従い、AWS上にアップロードしておきます。
また、latestの状態ではGreengrassにデプロイできないので、バージョン発行と、必要であればエイリアス発行も実施しておきます。

Lambda関数の準備周りの手順はこちらをご参照ください。
Lambda 関数の作成とパッケージ化

3. AWS IoT Greengrassをローカルで実行

まずは先ほどダウンロードしてきた証明書情報などを所定のフォルダに準備しておきます。 最後のdocker runだけは少しコマンドを追加しますが、基本的にはチュートリアル通りに実施すれば問題ありません。

改めてリンクを再掲します。 Docker コンテナでの AWS IoT Greengrass の実行

なお、証明書と設定フォルダが入ったgzファイルを解凍する作業では、Windowsだけで行う場合はWinZipや7-Zipなど、解凍のためのツールが必要になります。 面倒な場合は別のところで解凍しておいたほうが楽かもしれません。

証明書と設定フォルダ、ルートCA証明書の準備ができたら、はじめにダウンロードしてきたイメージをdocker runで起動します。

ここでは、今回の目的であるcsvファイルの読み込みのため、ローカルのcsvファイルへのマウント情報を追加しています。 (-v c:/Users/%USERNAME%/Downloads/gg_data_root:/tmp/gg_data_root のところ)

お手本のコードにマウントに必要なコマンドが記載されているので、書き方はそこを参照すると良いかと思います。

docker run --rm --init -it --name aws-greengrass-docker --entrypoint /greengrass-entrypoint.sh -v c:/Users/%USERNAME%/Downloads/certs:/greengrass/certs -v c:/Users/%USERNAME%/Downloads/config:/greengrass/config -v c:/Users/%USERNAME%/Downloads/gg_data_root:/tmp/gg_data_root -p 8883:8883 216483018798.dkr.ecr.us-west-2.amazonaws.com/aws-greengrass-docker/amazonlinux:latest

無事Greengrassが起動できると、コマンドプロンプトは下記のような状態になります。

f:id:brains_iwaki:20190124185247p:plain

この状態であれば、Greengrassが正しく起動しています。

4. Greengrassグループの設定

次はいよいよクラウド上でGreengrassの設定を行い、エッジ側に情報を配信 (デプロイ)します。

ここでは、コンソール上のAWS IoT Greengrassのページから、2番目の項目で作成したGreengrassのグループに、各種設定をつけていきます。

今回設定を行うのはLambda関数とサブスクリプションの設定の2つだけです。 ローカルリソースアクセスやコネクタ、ML推論などの機能は、コンテナなしの設定では使用できません。

更なる応用を見越した場合、ロールの割り当てやCloudWatchにログをあげる設定などを適宜行うことになりますが、 このトライアルではそれらの設定は不要です。

Lambda関数

まずは関数の設定を3箇所実施します。

下記の画像のように、

  • コンテナ化: コンテナなし
  • タイムアウト: 30秒
  • Lambdaのライフサイクル: 存続時間が長く無制限に稼働する関数にする

という設定にします。

f:id:brains_iwaki:20190124185702p:plain

次に、Lamba関数で使用する環境変数も設定しておきます。

f:id:brains_iwaki:20190124185347p:plain

ここで使用するトピックはサブスクリプションとテストで使用します。

また、データへのパスは、先ほどdocker runさせた時にマウントさせたパスにします。
今回は、/tmp/gg_data_root_data_dir/sample_dataの直下にcsvが入るようにマウントさせていることに注意してください。

サブスクリプション

HelloWorld関数のチュートリアルを元に、相互にやり取りできるように設定します。 今回は下記のような設定にしました。

f:id:brains_iwaki:20190124185802p:plain

解説

もともとのGreengrassではLambda関数の起動のたびにコンテナを立てていたのですが、この設定により、Lambda関数をOSプロセスとして実施できるようになり、 Docker上で動作できるようになった、という話のようです。

一方、「コンテナなし」の設定にすることで、ローカルリソースアクセスやコネクタ、Greengrass ML Inferenceなどの機能が使えなくなるといデメリットがあります。 ローカルリソースアクセスについては、この記事で紹介しているように直接アクセスの設定をすることで回避できますが、 他の機能を使っている場合は何か対策を行う必要が出てきます。

ちなみに、Greengrass ML InferenceはAmazon SageMakerやS3にあるモデルソースを使ってMLワークフローをシンプルに行うためのサービスで、 Lambda上で動かすなどの一般の機械学習とは特に関係ありません。そちらはコンテナなしでも普通に使うことができます。(ライブラリの準備等は必要です)

5. デプロイ実施

無事グループの設定が完了したら、Greengrassをデプロイします。 Greengrassが正しく起動した状態で、設定が適切になされていれば、グループの情報がエッジ側に配信されます。

f:id:brains_iwaki:20190124185927p:plain

配信後、左上の表示が正常に完了したことを示したら、テストを実施します。

6. テスト

最後にテストを行います。ここではGreengrass自体のチュートリアルのHelloWorld関数のテストと同様の設定を行います。 AWS IoTのコンソールのテストのページで下記のようにトピックのサブスクライブを行い、起動側のトピックを発行します。

f:id:brains_iwaki:20190124190050p:plain

すると、次の画像のように、デプロイしたLambda関数が動作し、csvファイルのファイル名と、1行目を読み込んだ結果をAWS IoT側に送信してきます。

f:id:brains_iwaki:20190124190104p:plain

今回はダミーのデータを入れたsample1.csv, sample2.csvという二つのファイルを準備していたので、 それらのファイル名と1行目の内容を送信してきてくれています。

これで、ファイルの読み込みが正しくできたことが確認できました。

今後の応用

以上、Dockerコンテナ上で起動したGreengrassを用いてのWindows上のファイル読み込みの簡単なトライアルを行いました。

ファイルの読み込みができたので、今後は本格的なデータ活用に進めていくことになるかと思います。

今回はAWSが提供したイメージをそのまま使用しましたが、既存ライブラリの活用とLambda関数の容量制限等を踏まえると、 ソフトウェアとして継続的に使用していくためにイメージの拡張が必要になってきそうです。

まとめ

以上で今回の記事は終了です。

長くなってしまいましたが、これでようやく本格的なGreengrassの活用に向けてのスタートラインに辿り着きました。 このステップは前提として、次にどのようにデータを活用していくか、あるいはアプリケーションをどのように構成していくかといった 本格的な取り組みに進んでいくことになると思います。

この技術を生かしてより一層データ活用が進んで行くことを期待しています。


ブレインズテクノロジーでは「共に成長できる仲間」を募集中です。
採用ページはこちら

参考資料

Dockerコンテナ上で起動したGreengrassとWindowsとの連携で広がる新たなデータ活用の選択肢

こんにちは、ブレインズテクノロジーの岩城です。

2018年11月末に開催されたAWS re:Invent2018で、AWS Greengrass IoTをDockerコンテナ上で起動できるようになったことが発表されました。これにより、GreengrassをWindows上で活用する際のハードルが下がり、データ活用を検討する際の選択肢がこれまで以上に広がっています。

今回の記事ではエッジコンピューティングに関する最近のトピックとして、GreengrassをWindowsと連携することで可能になった新しいデータ活用のイメージを紹介します。

より技術的なことに焦点を当てた記事も後日公開予定なので、実際にGreengrassをWIndows上で動かすことに興味がある方はこちらもご参照ください。

[2019年2月4日追記]
GreengrassをDocker for Windowsで使用するまでの準備と、今回テストとして実施した内容をまとめた記事を公開しました。

blog.brains-tech.co.jp

背景

従来は、GreengrassのソフトウェアはLinux系のパッケージのみで提供されており、かつDockerコンテナ上で動かすことはできませんでした。

しかし、AWS re:Invent2018で発表があったように、現在はGreengrassをDockerコンテナ上で起動することができるようになっています。

aws.amazon.com

Linuxだけでなく、WindowsやmacOS上からでもコンテナ経由でGreengrassをより容易に使えるようになった結果、 データを収集するところからの他のデバイスとの連携という点を含め、これまではなかった効率的なデータ活用の選択肢が生まれています。

実際にどのように可能性が広がったかより明確にするため、この技術の活用イメージとして生産現場からGreengrassまでのデータの流れの一例を紹介します。

AWS IoT Greengrassとは

補足として、AWS IoT Greengrassについても簡単に紹介しておきます。

AWS IoT Greengrass (以下Greengrass)はクラウドのAWSの機能の一部をローカルデバイスでも実行できるようにすることができるソフトウェアです。 例えば、弊社の場合はクラウドで提供している異常検知機能をローカルのコンピュータ (エッジコンピュータ)で実行するために使用しています。

ざっくりとした説明ですが、Greengrassを使用することで、クラウド環境で動作している一部のアプリケーションをローカル(エッジ側)のPCでも動作させることができ、 連携対象の設定などもまとめて行うことができると認識いただければ良いかと思います。

クラウドで使用している機能やデバイス間の設定をインターネット経由でエッジ側に配信するので、 ソフトウェアのアップデートやシステムの設定を少ない労力で実施できるほか、スケールさせやすいなどのメリットがあります。

AWS IoT Greengrassについては、こちらの資料も分かりやすかったのであわせてご参照ください。

dev.classmethod.jp

そもそものエッジコンピューティングのメリットとしては、データを取得したその場で実施したい処理を行うことができるため、少ない遅延で結果を得られることや クラウドに送るデータをエッジ側で加工することで、データの送信量を削減できることなどがありました。

他にもいくつかメリットがあるので、エッジコンピューティングそのものに興味がある方は弊社CTO中澤も登壇したAWS re:Invent:2018: Machine Learning at the OkO Edge (IOT214)(英語)、弊社林の過去の登壇資料AWS summit 2018の資料などをご参照ください。

re:Invent2018の映像はAWS Senior ManagerのDavid Nunnerleyによるご講演から始まり、18:12頃からアイシン・エィ・ダブリュ株式会社の佐藤雅則様のご講演、27:55頃から弊社中澤の講演という構成になっています。

www.youtube.com

www.slideshare.net

blog.brains-tech.co.jp

https://d1.awsstatic.com/events/jp/2018/summit/tokyo/aws/12.pdf

活用イメージ例

生産現場からのデータの集約・加工

生産現場などのデータを活用するためには、まずはデータを集約し、使える形にする必要があります。

このような役割を果たす仕組みや設備は数多くあるかと思いますが、今回は三菱電機の産業用PC MELIPC1002-Wを使用した場合の例を紹介します。

MELIPC MI1002-Wは、下記の画像に示したような、およそ15cm x 20cmのほどの産業用PCです。

f:id:brains_iwaki:20190124182856p:plain
MELIPC1002-Wの外観

MELIPCはWindowsを搭載しており、主にデータを集約・加工する役割と、次のデータ活用のインターフェイスとしての役割を持ちます。

また、データの集約・加工という観点では、MELIPCは「Edgecross」という、データの収集・加工のためのソフトウェアを標準でインストールしています。

このソフトウェアを使用することで、各種機器からデータを集約し、 設定に応じて加工を施した後にcsvファイルやデータベース(PostgresSQL)に保存することなどを行うことができます。

技術的な検討を実施するにあたり、今回MELIPCの実機をお借りすることができたので、そちらで行った設定や検証については別記事でご紹介します。

MELIPCおよびEdgecrossの詳細については下記の製品ページや紹介ページをご参照ください。
http://www.mitsubishielectric.co.jp/fa/products/edge/melipc/items/mi1000/index.html
https://www.edgecross.org/ja/edgecross/

集約・加工されたデータの活用

MELIPCによって収集・加工されたデータはWindows上などに保存されます。このデータをDocker for Windows経由でWindows上で動作しているGreengrassが読み出し、より高度なデータ活用を行います。 ここでのデータ活用としては、例えば弊社の場合のGreengrassを用いたエッジ環境上での異常検知が分かりやすいと思います。

ここまで紹介した例でのデータの流れを一旦整理すると下記のようになります。

  1. まずは生産現場などでデータを取得。
  2. 取得したデータをMELIPC上のEdgecrossにより集約・加工し、MELIPC内のWindows上などに保存。
  3. 保存したデータをDocker on Windows上のコンテナ内で動作しているGreengrassが読み出し、異常検知などの用途に活用。

あくまでも一例ですが、このような流れで得られたデータを使うことができます。

Greengrassからクラウドへのデータ連携

Greengrassで目的の用途で使用された後の結果やデータなどは、次の目的に応じ、クラウドにアップロードすることができます。 クラウドへのアップロードには通常のネットワークを使用する他、SORACOMさんが提供しているIoT向けの安価なワイヤレス通信を利用する選択肢があります。

soracom.jp

データをアップロードする場合は、例えば新規に得られたデータを使って異常検知モデルを更新したり、他の分析に使用することができます。

もちろん、データのアップロードは行わず、異常検知結果や実施した記録だけをクラウドに記録すしたり、あるいは全く何もしないという選択肢もあります。この辺りはどのようにデータを使いたいか、という方針に従って決めていくことになります。

活用イメージ例のまとめ

以上を踏まえ、MELIPCによるデータ収集、SORACOMのサービスを利用したクラウドとの連携、弊社の異常検知サービスImpulseをGreengrass上で使用した場合のデータ活用例の全体像をまとめたものが下記の図です。

f:id:brains_iwaki:20190129123450p:plain
GreengrassとWindowsの連携を利用したデータ活用イメージ例

データ収集技術や通信技術などの従来から実現していた仕組みに加え、今回可能になったGreengrassとWindowsの連携により、これまで以上にデータ活用の選択肢が広がっていることを感じていただけますと幸いです。

まとめ

GreengrassがDocker上で起動できるようになったことをきっかけに広がった選択肢や活用イメージ例について、MELIPCやSORACOMなどの既存サービスとの連携も含めて紹介しました。

今回の技術的進歩がもたらした大きなメリットは、使いたいデバイスやソフトウェアがある場合や、既に導入している機器をベースに新しい取り組みを行いたい場合などに可能な選択肢が増えたことにあるのではないでしょうか。

用途やアプローチは数多くあるかと思いますが、この技術で広がった選択肢により、世の中のデータ活用が更に進むことを期待しています。


ブレインズテクノロジーでは「共に成長できる仲間」を募集中です。
採用ページはこちら

参考資料

速報 re:invent 2018

こんにちは、ブレインズテクノロジーの佐々木です。現在AWSのイベントであるre:invent 2018に参加しています。

こちらの時間で11月28日(水)の午前中にCEOのAndy Jassyによる基調講演が行われました。 基調講演は例年新しいサービス・機能が発表される場であるため、毎年非常に注目されています。

今年もたくさんの新サービスが発表されましたので、簡単に紹介したいと思います。 なお、この記事は速報のため、内容に誤りがある場合がございます。ご了承ください。

f:id:ryotasasaki:20181129042326j:plain
会場の様子

続きを読む

JavaScriptでデータフレーム操作 - dataframe-js -

はじめに

こんにちは、ブレインズテクノロジーの佐々木です。4月に新卒で入社しました。学生時代は熱帯林を這いつくばって植物と戯れていました。

CSVからデータを読み取って、ちょっとした分析をしたい!というシーンはよくありますよね。そうした手軽なデータ操作のツールとしては、PythonのpandasやRのdplyrなどが機能も充実していて使いやすいため、人気があるようです。また、大量のデータを製品環境で扱うような場面では、hadoopやsparkなどの分散処理基盤を活用することも多いようです。ただ、これらの選択肢が便利すぎるがゆえに、フロントエンドでデータ操作に迫られたときにストレスを感じる人も多いのではないでしょうか。

ということで、今回は、ブラウザ上でも便利にデータ操作ができるJavaScriptライブラリ、dataframe-jsに入門します。

インストールと準備

といいつつ実際にブラウザで動かすのは面倒なので、今回はnode上で動かします。基本的にはブラウザでも同様に動く(と信じて)います。またもっと手軽に試したい方はJupyter notebookにIJavaScriptカーネルを入れると良いかもしれません(ここまでやると、pandas使えよ!ってツッコミが入りそうなのでやめました)。

npm install dataframe-jsでインストールできます。 前提として、以下のようなディレクトリ構成で作業しています。

.
├── iris.js
├── main.js
├── package.json

csvからデータを読み込む場合、データそのものではなくてPromiseが返ってきます。今回は以下のようなIrisクラスにメソッドを書き加えて、main.jsから呼び出す形で作業を進めて行きます。

  • iris.js
const DataFrame = require('dataframe-js').DataFrame;

module.exports = class Iris {
  constructor(params) {
    this.url = params.url;
    this.dfPromise = DataFrame.fromCSV(this.url);
  }
  
  showDF() {
    this.dfPromise.then(df => {
      df.show();
    });
  }
}
  • main.js
const Iris = require('./dataframe');

const iris = new Iris({
    url: 'https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv'
});

iris.showDF();

node main.jsで実行します。

ちょっとアヤメの話

それでは本題に入ります。この記事のゴールは、iris(アヤメ)データセットを用いて種ごとに花弁(petal)と萼片(sepal)のサイズの関係を調べ(て、I. versicolor, I. virginica, I. setosa各種の形態的特性とその適応的意義について考察す)ることとします。

USDA Forest Serviceによると、この三種はいずれも湖畔沿などの湿地に生息しsetosa(アラスカ), versicolor(五大湖付近), virginica(ニューヨークからフロリダまで)の順に寒冷地に分布しています。一般に寒い方が大気飽差が小さく(相対湿度が大きく)蒸散で水を失いにくいことが知られています。また、組織が幅広だと乾燥重量あたりの蒸散量が増えるので、virginica, versicolor, setosa の順に花弁および萼片が細長であるという仮説をたてました。

この仮説を検証するために、各3種ごとに花弁と萼片の縦横の比の平均と標準偏差を計算し、比較します。

f:id:ryotasasaki:20181009144400p:plain http://suruchifialoke.com/2016-10-13-machine-learning-tutorial-iris-classification/

データ分析

まずはデータの基本的な整形をしてみます。行のフィルターにはfilter, 列の選択にはselectが使えます。使い方はpandasというよりも、Rのdplyrやsparkのデータフレームに似ています。

  • iris.js
filterAndSelectDF() {
    this.dfPromise.then(df => {
      df
        .filter(row => row.get("species") === "versicolor")
        .select("sepal_length", "sepal_width", "species")
        .show(3);
    });
}
  • 結果
sepal_length sepal_width species
7 3.2 versicolor
6.4 3.2 versicolor
6.9 3.1 versicolor

次に、花弁縦横比(縦/幅)を計算してみます。

  • iris.js
mutateWLratio() {
    this.dfPromise.then(df => {
      df
        .map(row => row.set('sepal_wlratio', row.get('sepal_length') / row.get('sepal_width')))
        .map(row => row.set('petal_wlratio', row.get('petal_length') / row.get('petal_width')))
        .select("sepal_wlratio", "petal_wlratio", "species")
        .show(3);
    });
}
  • 結果
sepal_wlratio petal_wlratio species
1.4571 6.9999 setosa
1.6333 6.9999 setosa
1.46875 6.5 setosa

最後に、種ごとにグループ演算をして各種の形質の平均・標準偏差を求めます。groupByで指定した列に対しGroupedDataFrameオブジェクトが返されます。GroupedDataFrameオブジェクトはaggregateメソッドをもち、グループ(種)ごとに関数を適用できます。

今回は花弁・萼片それぞれに平均と分散を種ごとに計算し、一つのデータフレームにまとめています。

  • iris.js
calcSppStats() {
    this.dfPromise.then(df => {
      const groupedDF = df
      .chain(
        row => row.set('sepal_wlratio', row.get('sepal_length') / row.get('sepal_width')),
        row => row.set('petal_wlratio', row.get('petal_length') / row.get('petal_width'))
      )
      .select('sepal_wlratio', 'petal_wlratio', 'species')
      .groupBy('species');
      groupedDF
        .aggregate(group => group.stat.mean('sepal_wlratio'))
        .rename('aggregation', 'sepal_wlratio_sp_mean')
        .join(
          groupedDF
            .aggregate(group => group.stat.sd('sepal_wlratio'))
            .rename('aggregation', 'sepal_wlratio_sp_sd')
        , 'species', 'inner')
        .join(
          groupedDF
            .aggregate(group => group.stat.mean('petal_wlratio'))
            .rename('aggregation', 'petal_wlratio_sp_mean')
        , 'species', 'inner')
        .join(
          groupedDF
            .aggregate(group => group.stat.sd('petal_wlratio'))
            .rename('aggregation', 'petal_wlratio_sp_sd')
        , 'species', 'inner')
        .show(3);
    });
}
  • 結果
species sepal_wlratio_sp_mean sepal_wlratio_sp_sd petal_wlratio_sp_mean petal_wlratio_sp_sd
setosa 1.4745 0.1186 7.0779 3.1237
versic 2.1604 0.2286 3.2428 0.3124
virginica 2.2304 0.2469 2.7806 0.4073

また、group.stat.statsというメソッドを使うと各種統計量がまとめて計算できます。

分析まとめ(アヤメ)

以上の結果をテーブルにまとめました。

species 花弁縦横比(縦/幅)・平均 ± 標準偏差 萼片縦横比(縦/幅)・平均 ± 標準偏差
setosa 1.48 ± 0.12 7.10 ± 3.12
versicolor 2.16 ± 0.23 3.24 ± 0.31
virginica 2.23 ± 0.25 2.78 ± 0.41

花弁は仮説の通り、virginica, versicolor, setosa の順に細長でした。しかし、萼片については反対にsetosa, versicolor, virginicaの順に細長でした。考察として、花弁や萼片の形状(縦横比)だけでなく面積そのものや生理学的特性も考慮する必要があると考えられます。

まとめ(dataframe-js)

流石にpandasには劣りますが、基本的なデータ操作はストレスなくできた気がします。クライアント側でデータ操作がスムーズにできることで、plotly.jsなどと組み合わせて(df.toCollection()とすると簡単にオブジェクトに変換できます)1. リッチな可視化が比較的簡単に実装できるようになる、2. pandasなどを使ってデータ処理をするためだけにサーバーサイドに処理を投げる必要がなくなりデータフローがすっきりさせられる、などのメリットがあるのではないでしょうか。

追記

はてなブログでJavaScriptが実行できることを知ったので、一応試しておきました。表示ボタンを押すとhttps://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv のデータがロードされ、一連のこれでブラウザでも同様に動く(と信じて)ことも確認できました。

結果はここに出ます。
<script src="https://cdn.rawgit.com/Gmousse/dataframe-js/master/dist/dataframe-min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

<input id='show_button' type=button value='表示'>
<script type="text/javascript">
$(function() {
    $('#show_button').click(function() {
        const DataFrame = dfjs.DataFrame;
        DataFrame.fromCSV('https://raw.githubusercontent.com/uiuc-cse/data-fa14/gh-pages/data/iris.csv')
            .then(df => {
                const groupedDF = df
                    .chain(
                    row => row.set('sepal_wlratio', row.get('sepal_length') / row.get('sepal_width')),
                    row => row.set('petal_wlratio', row.get('petal_length') / row.get('petal_width'))
                    )
                    .select('sepal_wlratio', 'petal_wlratio', 'species')
                    .groupBy('species');
                const resDF = groupedDF
                    .aggregate(group => group.stat.mean('sepal_wlratio'))
                    .rename('aggregation', 'sepal_wlratio_sp_mean')
                    .join(
                        groupedDF
                        .aggregate(group => group.stat.sd('sepal_wlratio'))
                        .rename('aggregation', 'sepal_wlratio_sp_sd')
                    , 'species', 'inner')
                    .join(
                        groupedDF
                        .aggregate(group => group.stat.mean('petal_wlratio'))
                        .rename('aggregation', 'petal_wlratio_sp_mean')
                    , 'species', 'inner')
                    .join(
                        groupedDF
                        .aggregate(group => group.stat.sd('petal_wlratio'))
                        .rename('aggregation', 'petal_wlratio_sp_sd')
                    , 'species', 'inner');
                const resJSON = JSON.stringify(resDF.toCollection(), null, 2);
                $('#result').text(resJSON);
            })
    });
});
</script>


ブレインズテクノロジーでは「共に成長できる仲間」を募集中です。
採用ページはこちら

参考