ゼロから学ぶディープラーニング – AWS上のJupyterを使ったハンズオン

Japanese

ファイル 内容
ハンズオン・レクチャー資料 グロービス 人工知能研究会/テクノベート勉強会で用いたレクチャー資料
AWS_SETUP.md AWS上にJupyter環境を構築するためのガイド
file1_vector_and_matrix.ipynb ベクトルと行列
file2_two_layer_NN.ipynb ニューラルネットワークを行列計算で表現する
file3_gakusyu.ipynb 手書き文字(数字)認識の実践
file4_hyper_parameter.ipynb より高い精度を出せるハイパーパラメータの探求
file5_CNN.ipynb 畳み込みニューラルネットワークの評価

English

File Contents
AWS_SETUP_E.md Building Jupyter Environment on AWS
file1_vector_and_matrix_E.ipynb Vector and Matrix
file2_two_layer_NN_E.ipynb Neural-Network Expression by Matrix
file3_gakusyu_E.ipynb Hand-writing Digits Recognition
file4_hyper_parameter_E.ipynb Finding Hyper Parameters for Higher Accuracy
file5_CNN_E.ipynb Convolutional Neural Network Estimation

続きを読む

Amazon Translateを使ってみた&自動翻訳付きチャットを作ってみた

Amazon Translateのプレビュー申請が先日通ったので、使ってみました。us-east-1(バージニア北部)で利用しています。

Amazon Translateとは?

公式ページへどうぞ。

成果物

とにかく成果物が早く見たい方はこちらへ。

https://github.com/kojiisd/amazon-translate-chat-demo

コンソールから使ってみる

とりあえずAWSコンソールから使ってみます。100万文字で15ドルの料金のようです。

スクリーンショット 2018-01-13 16.05.42.png

選択できる言語は7つとまだ少なめですが、いずれすぐに日本語も追加されるでしょう。

image.png

入力した文字がリアルタイムに翻訳されます。(日本語が選択できないので、文章を入れても自然な文章になっているのかは判断できませんがw)

スクリーンショット 2018-01-13 16.08.49.png

APIを使ってみる

ただこれだけだとなんの面白みもないので、自動翻訳をつけたようなチャットを作ってみたいと思います。

画面の準備

以前作成したiot-demo-deviceをベースに開発します。

https://github.com/kojiisd/aws-iot-demo-device/

とりあえずこんな感じの画面を組みます。

スクリーンショット 2018-01-20 13.26.33.png

項目名 意味
Name 名前
Source Language 受信するメッセージの言語
Target Language 翻訳対象言語
Start Chat チャット開始のためのボタン
Message メッセージ
Send Message メッセージ送付用ボタン

最初は名前やメッセージ受信時の言語を選択しないとチャットを
スタートできないようにしています。
→メッセージをSubscribeする際に自身と同じ名前だったら翻訳しないようにするため。

画面下部の「Original」と「Translated」にメッセージのやりとりが記録されるように実装します。

WebSocketにAWS IoTを利用する

チャットのやりとりをするために今回WebSocketを利用しますが、一から環境を用意するのが面倒なので、AWS IoTで手を抜きます。カスタマイズなどは特に気にせずデフォルトで設定してしまってOKです。

今回はこちらの記事と同じ設定をしました。

Three.jsとAWSを連携させてIoTっぽいことしてみた

AWS IoTは受信後のアクションが必要だったので、DynamoDBに履歴として登録する体で設定をしています。

aws-sdkのフルビルド

この記事を書いている時の「v2.184.0」ではフルビルドをしないとAWS.Translateクラスが使えなかったため、公式ページを参考にビルドを実施します。

https://docs.aws.amazon.com/sdk-for-javascript/v2/developer-guide/building-sdk-for-browsers.html

$ git clone git://github.com/aws/aws-sdk-js
$ cd aws-sdk-js
$ npm install
$ node dist-tools/browser-builder.js all > aws-sdk-full.js

翻訳部分を開発する

肝心の翻訳ですが、こんな感じのコードにします。事前にCredentialやEndpointなど必要な情報を設定しておく必要があります。なぜPromiseが必要かは後述します。

AWS.config.credentials = new AWS.Credentials(cred.awsAccessKeyId, cred.awsSecretAccessKey);
  :
  :
function translate(message) {

  var params = {
    Text: message,
    SourceLanguageCode: srcLang,
    TargetLanguageCode: targetLang
  };

  var syncProc = new Promise(
    function (resolve, reject) {
      window.translator.translateText(params, function onIncomingMessageTranslate(err, data) {
        if (err) {
          reject("Error calling Translate. " + err.message + err.stack);
      }
        if (data) {
          resolve(data.TranslatedText);
        }
      });
    }
  );

  return syncProc;
}

翻訳語の文章の追加部分の開発

上述のtranslateメソッドを呼び出す部分ですが、メッセージ受信後のコールバックメソッドとなります。

function onMessage(message) {
  var msgJson = JSON.parse(message.payloadString);
  var addingHtml = "<tr><td>" + msgJson.name + ": </td><td>" + msgJson.message + "</td>";
  if (msgJson.name == body.name) {
    addingHtml += "<td></td><td></td></tr>"
    $("#chatArea").prepend(addingHtml);
  }
  else {
    translate(msgJson.message).then(function (result) {
      addingHtml += "<td>" + msgJson.name + ": </td><td>" + result + "</td></tr>"
      $("#chatArea").prepend(addingHtml);
    }).catch(function(error){
      alert(error);
    });
  }

メッセージを受信した際、自身の名前と同じであれば翻訳は実施しないように処理をしています。

自分ではない人からのメッセージの場合translateメソッドを呼び出しますが、Translate APIにアクセスするタイミングで非同期処理となってしまうため、前述のPromiseでこの辺の処理の順番を制御しました。

実際の動き

画面を二つ用意して、それぞれ「kojiisd1」と「kojiisd2」でチャットを開始するようにします。設定はそれぞれ以下の通りとします。

kojiisd1 kojiisd2
Source Language French English
Target Language English French

kojiisd1からは英語で話すようにし、kojiisd2からはフランス語で話をしてみます。

こんな感じで操作できました(ちょっとGIFのサイズ大きい)。

amazon-translate-chat-demo3.gif

まとめ

Amazonが提供する翻訳サービスなので、Pollyなど他のサービスとの連携も容易にできるようになると期待が持てます。これは電話会議などもAmazonが提供する翻訳サービスを使いながらリアルタイムに全て自動翻訳できる日が来そうな感じがして、期待大のサービスですね。

続きを読む

AWS Snowball Edgeが我が家にやってきた。

概要

AWS Snowball Edgeを注文して自家用で使うべく注文した話です。
到着後に技術的に使用する話は別記事になっています

やっと来たSnowball

従来のAWS Snowballは専用のツールでデータを格納してS3とデータを出し入れするだけのストレージでした。
そこにAWS Snowball Edgeが登場。名前は似ているがこれは別物らしい。

NFS対応アップデート登場

AWS Snowball Edge登場当初は、ただのS3互換ローカルストレージでした。
2017年6月のアップデートでNFSサーバとして接続できるFile Interface機能が登場。
NFSサーバとしてローカルストレージにできる!?
申し込もう。

アマゾン時間

2016年内に全リージョンでGAとなるはずだったAWS Snowballなのに来る気配が無い。
2017年春、クローズドで一部パートナー等に出しているという話を聞くも自家用には借りられない。
2017年9月、やっと来た。
アマゾン時間はJSTと9ヶ月の時差があるようです。

申し込めないよSnowball

早速申し込もうとするもTokyoは日本の都道府県ではないと弾かれ申し込めません。
snow11.jpg

東京独立国構想も悪くないね!?
しかしどの都道府県を選択しても同じで申し込めず、サポートへ問い合わせ。

サポートからの返事は…
snow12.jpg

なんと言語設定をEnglishにして申し込んでくれというものでした。
ぶひー!!
(注:本不具合は2018年1月現在、修正済みです)

外人から連絡が><

申し込みを終えると、何やら外人からサポートケースを開かれ横文字で質問が来ました。
sn1.jpg

け!また横文字かよ。
しかも「質問に返答するまでSnowballを出荷しない」と書かれています。
ヤンキーらしいなぁ。
と思いつつ、後にこれに助けられることとなるのでここはおとなしく。

内容はSnowballはこういう仕様だけど、利用用途と環境に問題無いかという申し込みの確認です。
30TB程のデータがあり、スイッチには10Gbps RJ45とSFPポートがあるよと答えると、出荷の準備に入ると連絡が来ました。

大人気のSnowball Edge

しかし待てど暮らせど届かない。マネコンの状況も変化せず1週間。
サポートケースに更新がありました。
sn2.JPG

Snowball Edgeデバイスが大人気ですぐには出荷できないとのこと。
S3へデータを輸送するだけならこの注文をキャンセルして50TBか80TBのSnowballを注文してくれと書かれています。
それでは意味がないですし、来月のJAWS FESTA向けのネタなので急ぎませんから気長に待つことにします。

それは突然に

大人気で出荷できないよと連絡が来た翌日はJAWS-UG長野をリブートしに出かけていました。
長野の支部長と信州盛りの大量に盛られた蕎麦を食べていると、かーちゃんから怒りの電話が。
 「あんたまたアマゾンに何頼んだの。大きい荷物が届いたけど重くて動かせないよ」
と怒っています。

何か注文した記憶はありません。
ん!?!?
まさかとマネコンを開くと。。。

sn3.jpg
配達済みとか書かれています。
どうやらそのようです。長野遠征中につき2日間おあずけとなりました><

普通の宅配便として届くSnowball

日通警備さんとかが警備しながら持ってくるのかなと思いきや、宅配便の荷物として普通に届きました。
日本では西濃運輸さんが担当されているようです。
sn4.jpg

アクティベーションしないと使えませんし、配送は適当でも問題ないのでしょうね。
メソさんのブログによると欧州では玄関先に放置配達されたようですし対面受取なだけ日本はマシかも?

しかも外箱などは無く、筐体へ配達伝票と納品書がそのまま貼り付けられて届きます。
確かに物理的衝撃に強い構造ですから梱包不要でしょうけど、なんか面白いですね。

Eインクは?

上部にはEインクの表示パネルがあり、配達先等が表示されています。
sn5.jpg

電源が無くても光るんですね。背面のバックライト?はずっと光っていました。
しかし西濃運輸さんが非対応なのか、通常の宅配伝票が筐体側面に貼られています。

開封の儀

SnowBall Edgeには3つの扉があります。

上部を開くと電源ケーブルが収納されているのでこれを取り出します。
sn6.jpg
付属品はこれだけです。
ネットワークケーブルは必要な物を自前で準備しなければなりません。

背面を開くとネットワークポートと電源コネクタがあるので、ネットワークケーブルと先ほど取り出した電源ケーブルを接続します。
sn7.jpg
図解で「電源接続時は蓋を上げた状態で使用し閉じるな」と書かれています。

当然ですよね。
sn8.jpg
開けるとこの状態です。
これを閉じて使用したら発熱ですぐに熱暴走することでしょう。

前面を開くと電源スイッチと操作パネルがあります。
sn9.jpg
電源ボタンを押すと動き出します。

中身はHDDだった

ゴゴゴゴゴゴとHDD駆動音らしき音がします。
どうやらSSD等の半導体記憶媒体ではないようです。
衝撃に耐えるのは停止状態のみで良いわけですから、HDDでも要件を満たせますからね。

返却もふつうの宅配便

使用後に電源を切ると、筐体上面のEインクは返送用の宛名ラベルになります。
sn10.jpg

しかし、これまたEインク非対応であります。米国のみのようですね。
同梱されている西濃運輸さんの印字済み伝票を筐体に貼り付けます。
sn11.jpg

あとは普通の宅配便同様、西濃運輸さんへ集荷を依頼します。
いつもの運ちゃんが集荷に来て回収されます。

返却処理には時間がかかる

AWSのデータセンタは非公開のため、西濃運輸さんの拠点へ届けられます。
その後、AWSへ輸送されますがこの一連の処理が完了するまで1週間かかります。
sn15.jpg
処理が完了すると、マネコンのジョブステータスが完了済みとなり終了します。

料金の計算方法

Snowball Edgeは300ドルの基本料金に10日間の利用期間が含まれています。
届いた当日と、集荷された日は利用日に含まれません。
届いた翌日から集荷される前日までが利用期間となります。
よって、今回のように不在なのに家族が受け取ると残念なことになります。
また、送料別途で往復で120ドルかかりますから最低利用料金420ドルと覚えておきましょう。

まとめ

どんな物流なのか楽しみにしていましたが、普通の宅配便で届くことがわかりました。
一般のご家庭にも安心して注文できますね。一家に一台 AWS Snowball Edge.
利用開始後の技術的な話は別記事になっています

続きを読む

最適なデータベースを選択するために考慮するべきこと

こんにちは!少し前までProgateでエンジニアのインターンをさせていただいておりました、chisatonと申します。
Progateのアドベントカレンダーに参加させてもらえるだなんて思ってもみなかったので、とても嬉しい限りです。

今私はエンジニアとして別の会社で働かせていただいているのですが、今の部署とProgateではAWSを使用しているという点で共通点があるため、今回はAWSのサービス紹介も兼ねて、どんな時にどのデータベースを選択すべきなのか、についてまとめてみようかと思います。
元ネタは、最近参加させていただいたラスベガスでのAWS re:Inventの”Which Database to Use When?”というセッションになります。
こちらに動画が既にアップされていますので、興味がある方はこちらを見てみてください。

DB選択においてまず考慮すべき3つの項目

  • Shape
  • Size
  • Compute

Shape

Row Store

行指向データベースで使用されているストア方式です。MySQLなどでよく使われている有名なやつです。
例えばとある会社員の基本情報をまとめる時に1人ずつレコード単位でデータをまとめます。

スクリーンショット 2017-12-09 17.28.35.png

例えば上図のようなデータの場合、赤枠で囲われている(行ごとの)データを一つのデータとして保存します。
その為、新しい社員が入ってきた場合は、一行データを追加するだけで済みますが、逆にここから社内の平均年齢を出したい時は一度全てのデータをとってきた上で年齢の項目だけに着目し、平均値を計算しなければなりません。

Column Store

列指向データベースで使用されているストア方式です。後述するAWSのRedshiftなどではこの方式が採用されています。
上記の会社員の基本情報を再び例としますと、項目ごと(列ごと)にデータを保存します。

スクリーンショット 2017-12-09 17.28.35.png

この場合、新しく社員が入ってきた場合に、各項目ごとに保存しなければならないため、今回は「社員ID」、「名前」、「年齢」に対して書き込みが発生します。Row Storeと比べると書き込みの量が増えますが、一方で社員の平均年齢を計算をしたい時は年齢の項目だけを取り出して計算すればいいので、複雑な処理をせずに済みます。
また、列指向の場合、連続する同じデータを圧縮して管理出来るというのもメリットでしょう。

Key-Value Store

ユニークな一つのキーに足して、一つの値を紐付けて保存する方式です。
例えば社員のIDに対して社員の名前を一対一で対応付けるとすると、下図のようになります。

1 : 佐藤
2 : 鈴木
3 : 髙橋
4 : 田中
5 : 伊藤

こうすることで、社員IDを使えば社員の名前を取得することができます。
Column StoreやRow Storeと比べるとデータ自体を複雑な構造のものにすることはできませんが、この場合社員IDでインデックスを張っているため、constantな時間で値を取得でき、非常に高速です。
インメモリキャッシュのredisなどではこの方式を利用しています。

Document Store

よくNoSQLの代表格としてDocument Storeが紹介されることが多いです。いわゆるスキーマレスな(上記のRow Storeのように各レコードごとに各項目を用意していない)データベースです。

例えば、人の経歴についてのデータを保存するDBを考えてみましょう。
スキーマなDBに保存すると考えると、どんな項目が必要でしょうか?名前に年齢に最終学歴…他はどうでしょうか?
もしかしたら人によっては他の人にはないような項目の経歴があるかもしれません。実は留学していた。実は多言語喋れる。こんな時に役立つのがDocument Storeです。

example.json
{"name": "佐藤", "age": 22, "edu-background": "Hoge University"},
{"name": "鈴木", "age": 24, "edu-background": "Fuga University", "foreign-lang": ["English", "Spanish"]},
{"name": "髙橋", "age": 25, "edu-background": "Fuga University", "foreign-lang": ["English"], "written-book": ["Intro to DB"]},
{"name": "田中", "age": 33, "edu-background": "Foo University",  "written-book": ["Intro to Java", "Advanced Java"]},
{"name": "伊藤", "age": 31, "edu-background": "Bar University",  "study-abroad": ["America", "Germany"], "foreign-lang": ["English", "German"]},

このようなDocument Storeの代表格としてはMongoDBやAWSのフルマネージドサービスDynamoDBなどが挙げられます。

Graph Store

データ構造の勉強をしてれば必ず出てくるグラフ構造のストア方式です。
よくFBのような友人どうしのつながりなどのデータを保存する際に使われる事が多いです。

例えば、アプリの機能として友人になった人の友人をおすすめの友人として紹介する場合、BさんがEさんと友達になると、BさんにはCさんFさんが「友達かも」と紹介されるような感じです。この時、既にAさんとは友達なので、紹介対象には入りません。
これを例えばスキーマなDBで友人の友人を探そうとすると、友人かどうかの中間テーブルを参照するなど、そこそこ複雑な処理が発生します。
もちろん、全体から特定のデータを取得したい時にはとあるノードから次のノードへとひとつひとつ探査をしていく必要があるため、全探査をしなくてはならないという短所もありますが、他のストア方式では届かなかった痒いところに手の届くストア方式であるかもしれません。

Time-Series Store

時系列に保存、取得するストアです。
スキーマかスキーマレスかというよりかは、とある指定した時刻の間のデータが取れるようなstoreの事を指します。
例えばDynamoDBではrange keyなるものが存在し、保存されたtimestampを元に指定された時間の範囲内のデータを取ってきたりすることができます。
株価の動向を見る時などには、保存しておいた株のデータを1日単位や一週間単位で取得したりすることができます。

Size

Size at Limit

想定されるデータのサイズは有限のデータ(bounded)でしょうか、それとも無限に流れてくるデータ(unbounded)でしょうか。
社員のデータを保存するのでしたら、データの量はたかがしれています。10人かもしれませんし、大規模な会社でも2000万人ぐらいでしょう。これはboundedなデータです。
一方でユーザが訪れたサイトの情報を保存するとしたらどうでしょうか?1日一人あたり10サイト訪れる事を考えると、1日で日本だけでも、約1.2億 * 10 = 12億のデータを保存する必要があります。これはunboundedなデータに当てはまります。

Working Set & Caching

実際に保存したデータはどの程度使用するでしょうか。
仮に10年分のデータをDBに保存したとしても、もしかしたら使うデータは過去1年分のデータであり、9年分のデータは滅多に使用しないかもしれません。こんな時は1年分のデータのみキャッシュしてしまうというのも手かもしれません。

Retrieval Size

取得したいデータは一つだけですか。それとも同時に複数のデータとってきたいでしょうか。
状況にもよりますが、取得したいデータが一つだけならkey-value Storeが圧倒的に構造が単純で高速でしょう。

Partitionable & Monolithic

扱うデータは意味のある単位で区切ることができるでしょうか。
誰がどこにいるかというデータは、場所単位で分割できます。
一方で社員の給料明細は意味のある単位で区切るのがちょっと難しいデータかもしれません。
この違いによっては、データの保存を分割したりして高速化を図ることが出来るかもしれません。

Compute

Compute Functions

データを取り出す際の関数やクエリはどんなものが想定できるでしょうか。
データの保存の仕方によってはクエリや処理が簡単にも複雑にもなります。

Throughput

どの程度DBに対してwriteとread数を要求するでしょうか。
readやwriteのスケールについても考える必要があります。

Latency

どのくらいデータの取得に対して遅延を許容するでしょうか。
データの分析であれば多少遅くとも許容できるかもしれませんが、今アプリケーションを使ってくれているユーザーに対してデータの取得で時間をかけるわけにはいきません。

Rate of Ingestion

どのくらいの割合でデータが挿入されるでしょうか。
bounded/unboundedでの前述例であれば、社員数のデータ挿入の割合はたかがしれてますが、訪れたサイトの情報のデータの挿入であれば一秒間に幾つものデータを漏らすことなくDBに保存しなければなりません。

AWSのDB一覧

それでは上記の3項目を踏まえた上で、AWSのDBサービスを見ていきましょう。

  • Amazon RDS
  • Amazon DynamoDB & DynamoDB Accelerator(DAX)
  • Amazon ElasticCache(Redis & Memcached)
  • Amazon Neptune

Amazon RDS

リレーショナル・データベースです。様々なDBエンジンがあり、その選択も適切に選択する必要があります。
が、やはりAmazon Auroraがすごいですね!MySQLよりは少しお高いですが、それ以上に良い機能が満載です。

Auroraは作られるとまず3つのAZに2つずつレプリケーション(同じDBを複数の場所に複製)します。
そして、仮にマスタのDBが死んでしまってしても、どれか他のスレイブDBがフェイルオーバー(マスタに昇格)します。
そのため、readのスケールが向上するだけでなく、障害耐性に対しても強いDBと言えるでしょう。
また、Auroraのストレージは、10GB単位で勝手に増えるため、ストレージの容量を常に監視する必要もありません。

ちなみに、今回のKeynoteではAuroraのまさかのmulti master機能が発表されました。
筆者はこの発表を聞いた瞬間発狂したのですが、まさかwriteがスケールする日が来ようとは…!!

Amazon DynamoDB & DynamoDB Accelerator(DAX)

image.png

Document Store方式のNoSQLデータベースです。

DynamoDBも作られるとまず3箇所のAZにレプリケーションされます。
ストレージに関しては、勝手にパーティショニング(データの分割)が行われるため、気にする必要はありません。
そして、RDSとの大きな違いとしてreadとwriteのスループットをこちらで指定することができます。
そのため、RDSでは実現できないような膨大な量のデータのreadやwriteに対しても対応できます。

そしてDynamoDB Accelerator(DAX)はこのDynamoDBのデータをインメモリキャッシュしてくれるサービスになります。
二年ほど前のre:Inventで発表されて以来、未だサービスとして使うことができない(2017年12月執筆時)のが残念ですが、後々はデータの取り出しが高速化し、またDynamoDBへのreadが減ることはとてもうれしいですね!

Amazon ElasticCache(Redis & Memcached)

AWSのマネージドインメモリキャッシュサービスになります。
インメモリなので、膨大な量のデータのキャッシュには向いてませんが、RedisにしてもMemcachedにしてもkey-value Storeなので非常に高速にデータを返すことができます。
その他にもRedisにはsorted setといった追加したデータの値に応じてソートしてくれる機能や指定したキーに対して、指定した地理情報(緯度経度)を保存する機能などがあります。
Memcachedに関しては、ノードを追加することが出来るため、readもwriteもスケールさせる事ができます。

Amazon Neptune

Graph型のフルマネージドデータベースサービスです。こちらも今回のre:Inventにて新しく発表されました!

スクリーンショット 2017-12-09 19.57.57.jpg

スケールが可能で、膨大な量のデータに対してミリ秒のクエリを使う事ができます。

こちらも3つのAZに足して6つのレプリケーションがなされるため、データを失う心配がほぼありません。
(筆者もこのへんはあまり詳しくはありませんが) 公式サイトによると、
Apache TinkerPop や W3C の RDF など一般的なグラフモデルと、TinkerPop Gremlin や RDF SPARQL など関連するクエリ言語をサポート
しているらしいので、既にどこかでGraph型のDBを使用されている方でしたら、比較的容易に扱えるかもしれません。

まとめ

以上、表にまとめると以下のようになります。
image.png

データ分析のためのAWSのサービス一覧

データを保存したら、次はデータの分析が必要になるかもしれません。DBサービスと共に分析のためのサービスも見てみましょう。

  • Amazon Athena
  • Amazon Redshift & Redshift Spectrum
  • Amazon Kinesis Analytics
  • Amazon Elasticserach

Amazon Athena

S3にあるファイルに対してSQLのようなクエリを投げることが出来るサービスです。
テーブル結合みたいなこともできるとか。
私の部署ではログの分析のするためにRedshiftを用いているのですが、いちいちログデータをRedshiftの方へコピーする作業が必要なため、現在Athena(またはRedshift Spectrum)を使おうかと検討中です。
分析した結果のデータを再び3Sへファイルとして保存したりできます。
クエリのページが完全にBigQuery

Amazon Redshift & Redshift Spectrum

フルマネージドなデータウェアハウスです。
このRedshiftは大量のデータをクラウド上に保持し、それに対してSQLライクなクエリでデータの解析、分析を行います。
イメージとしましてはAthenaの分析データがS3にファイルとして上がっているのに対して、Redshiftではクラウド上に分析しているデータを保存しているといった感じです。
また、Redshift Spectrumを使えば直接S3のファイルに対してクエリを投げる事ができます。こちらはAthenaとは違ってSpectrum専用のクラスタが複数立ち上がって処理を行ってくれます。

別記事ではありますが、Redshiftを既に使っている人向けのパフォーマンスチューニングの記事も書きましたので、よろしければこちらも参考にしてください。
Amazon Redshiftでより高速な処理を実現する

Amazon Kinesis Analytics

Kinesis Analyticsは取得したデータに対してすぐに分析や解析をしたい時に役立ちます。
unboundedな(無限に流れている)データに対して基本的に収集はストリーム処理をするかと思いますが、そのストリームデータに対してSQLで処理を行います。
他にもデータの変換を行ったり、またタイムウィンドウを設定することができるので、どのくらいの時間間隔でクエリを走らせるのかを自由に設定することができます。

Amazon Elasticsearch

Elasticsearchといえば全文検索のイメージが強いですね。
Elasticsearchはログデータをキャプチャし、それと同時にそのデータに対してうまくインデックスを張ります。
そのため、ログデータに対して非常に高速にクエリの結果を返すことができます。
全文検索に関しても、同じようにうまく独自のアルゴリズムでインデックスを張ることで、検索に対応しています。

まとめ

以上、表にまとめると以下のようになります。
image.png

全体まとめ

長くなってしまいましたが、以上、re:Inventで聞いてきたセッションについてまとめさせてもらいました。
普段どのDBを使うべきかを話すことってあまりないかと思うのですが、比較的サービスの根幹をなすものなので、上記知識はとても重要なものであると思います。
プレゼンターも言っていましたが、

Which Database to Use When?

ではなく

Which Database s to Use When?

であるべきである、と主張していました。

どんなサービスを提供するかにもよりますが、より良いサービスを届けるために、適材適所なDBや分析サービスを選択していくことがとても大切だなぁと感じた講義でした。

続きを読む

ラズパイでスマートスピーカーを自作(stretch)

myalexa.jpeg

ポストスマホの有力候補といえばスマートスピーカーということで、とりあえずデバイス側を作ってみました。
今回は米国で既に先行しているamazon Alexaとやり取りしたいと思います。
なんか色々アレクサと対話したいので英語、米語、ドイツ語、日本語と切り替えれるようにしました。

用意するもの

  • プロト基盤:Raspberry Pi3(2でも良いがwifiが付いているので3)
  • スピーカー:USB,3.5mmでもいいしHDMIでもいい
  • mircoSD:RSPIとの依存があるのでこの中から選ぶことを強くおすすめします。
  • USBキーボード:ラズパイ操作用
  • USBマウス:ラズパイ操作用
  • HDMIケーブル:モニターにつなぐため
  • HDMIモニタ:ラズパイ操作用
  • macbook:OSダウンロード用

大まかな流れ

ラズパイの設定
1. OSインストール
2. OSセットアップ
AVSの構築
1. SDKインストールと環境設定
2. SDKのビルド
3. AVSの認証
4. 実行

はい、では行ってみよう。

ラズパイの設定

1. OSインストール
まずはOS(raspbian)をインストールしましょう。
1. 1 OSのダウンロード
このサイトからダウンロード(https://www.raspberrypi.org/downloads/)

今回はraspbianというDebianベースのOSを使います。
ここにはNoobsという初心者用のインストーラーもあるけど、イケてる君は
Bootイメージを直接扱った方が時短になるので迷わずRasbian stretch2017-09-07を選ぼう。
※国内外の文献ではAVSのSDKがstretchに対応していないと書いているけど、そこはクリアしているので大丈夫。

1.2 SDカードのフォーマット

  • macbookにmicroSDカードを差す。
  • マウントが出来たらSDカードのフォーマットを行う。
  • SDカードの場所を確認
    $diskutil list
    これでSDカードのディレクトリが分かります。(ex:/dev/disk2)

  • SDカードのフォーマット(FATね)
    $sudo diskutil eraseDisk FAT32 RASBIAN MBRFormat /dev/disk2

    SDカードのサイズが30GB以下はFAT32とし、それ以上のサイズはexFATする。
    RASBIANは任意で好きな名前を付けてね

  • SDカードをアンマウントし、コピーができる状態が完了
    $sudo diskuitl unmount /dev/disk2
    disk2をアンマウントする

1.3 SDカードのコピー

  • ダウンロードしたOSを解凍
    $tar xzf 2017-09-07-raspbian-stretch.zip

  • 解凍したイメージをSDカードにコピー
    $sudo dd bs=1m if=2017-09-07-raspbian-stretch.img of=/deb/rdsik2

    なぜデバイス名rdiskになってるの?とお気づきですか。
    それはrdiskの方が書き込む速度が早いからです。
    disk2もrdisk2も同じ場所ですが、disk2とした場合、ランダムアクセスが可能となるデバイスとして転送データがUserSpaceという4KBのバッファを経由して処理されます。
    これはマルチタスクがゆえのことなのですが、これをrdiskで指定することにより、バッファを経由せずにダイレクトでシーケンシャルに処理が進むためにdiskよりも高速になります。
    興味と時間のある方はdisk指定で4GBのコピーの旅をお楽しみ下さい。

2 OSセットアップ
いよいよラズパイを動かしましょう。

2.1 OSの起動
RSPI3にモニタ、キーボード、マウス、SDカードを入れて電源ON
rasbian.jpeg

2.2 初期セットアップ

  • ターミナルを起動し次の設定を行う
    sudo raspi-configでもいいしGUIでもOK。とにかくこれを設定
    ・タイムゾーンの設定
    ・wifiの設定
    ・SSHの設定
    ・キーボード設定
    ※お好みに合わせてVNCも設定

AVSの構築

ここから本番。
1. SDKインストールと環境設定
1.1 まずは最低限必要なパッケージの更新とインストール

  • パッケージの更新
    sudo apt-get update

  • で、必要なパッケージをインストール

sudo apt-get -y install git gcc cmake build-essential libsqlite3-dev libcurl4-openssl-dev libfaad-dev libsoup2.4-dev libgcrypt20-dev libgstreamer-plugins-bad1.0-dev gstreamer1.0-plugins-good libasound2-dev doxygen

1.2 開発環境のディレクトリを作成

cd /home/pi/ && mkdir sdk-folder && cd sdk-folder && mkdir sdk-build sdk-source third-party application-necessities && cd application-necessities && mkdir sound-files

1.3 フリーの音声ライブラリ(portaudio)を拝借
ディレクトリ移動&ダウンロード&解凍&configure&makeを一気に行います

cd /home/pi/sdk-folder/third-party && wget -c http://www.portaudio.com/archives/pa_stable_v190600_20161030.tgz && tar zxf pa_stable_v190600_20161030.tgz && cd portaudio && ./configure --without-jack && make

1.4 commentjsonのインストール
AVS認証時に必要になるAlexaClientSDKConfig.jsonに書き込みを行うために必要
pip install commentjson

1.5 タイマーとアラーム音をアマゾンのサイトからダウンロード

cd /home/pi/sdk-folder/application-necessities/sound-files/ && wget -c https://images-na.ssl-images-amazon.com/images/G/01/mobile-apps/dex/alexa/alexa-voice-service/docs/audio/states/med_system_alerts_melodic_02._TTH_.mp3 && wget -c https://images-na.ssl-images-amazon.com/images/G/01/mobile-apps/dex/alexa/alexa-voice-service/docs/audio/states/med_system_alerts_melodic_02_short._TTH_.wav && wget -c https://images-na.ssl-images-amazon.com/images/G/01/mobile-apps/dex/alexa/alexa-voice-service/docs/audio/states/med_system_alerts_melodic_01._TTH_.mp3 && wget -c https://images-na.ssl-images-amazon.com/images/G/01/mobile-apps/dex/alexa/alexa-voice-service/docs/audio/states/med_system_alerts_melodic_01_short._TTH_.wav

2. SDKのビルド
2.1 AVSのSDKをクローンします

cd /home/pi/sdk-folder/sdk-source && git clone git://github.com/alexa/avs-device-sdk.git

2.2 ウェイクワードのエンジン(Sensory)もクローン
これをすると「アレクサ!」で反応してくれるようになります。

cd /home/pi/sdk-folder/third-party && git clone git://github.com/Sensory/alexa-rpi.git

で、それの利用規約に同意します。

cd /home/pi/sdk-folder/third-party/alexa-rpi/bin/ && ./license.sh 

2.3 日本語化対応
デフォルトは英語なので、これらのソースを変更し日本語に対応させます。

まずはエンドポイントを日本に変更

/sdk-folder/sdk-source/avs-device-sdk/SampleApp/src/SampleApplication.cpp
//68行目
// Default AVS endpoint to connect to.
static const std::string DEFAULT_ENDPOINT("https://avs-alexa-fe.amazon.com");

アプリ実行中のメニューに日本語切り替えを追加

/sdk-folder/sdk-source/avs-device-sdk/SampleApp/src/UIManager.cpp
//89行目のこのメニューに日本語を追加し、英語と入れ替える
static const std::string LOCALE_MESSAGE =
    "+----------------------------------------------------------------------------+n"
    "|                          Language Options:                                 |n"
    "|                                                                            |n"
    "| Press '1' followed by Enter to change the language to US English.          |n"
    "| Press '2' followed by Enter to change the language to UK English.          |n"
    "| Press '3' followed by Enter to change the language to German.              |n"
   "+----------------------------------------------------------------------------+n";
//を、次の内容に変更する
static const std::string LOCALE_MESSAGE =
    "+----------------------------------------------------------------------------+n"
    "|                          Language Options:                                 |n"
    "|                                                                            |n"
    "| Press '1' followed by Enter to change the language to Japan.               |n"
    "| Press '2' followed by Enter to change the language to UK English.          |n"
    "| Press '3' followed by Enter to change the language to German.              |n"
    "| Press '4' followed by Enter to change the language to US English.          |n"
    "+----------------------------------------------------------------------------+n";

メニューの変更をテーブルにも反映

/sdk-folder/sdk-source/avs-device-sdk/SampleApp/src/UIManager.cpp
//44行目 日本語を追加し、英語と入れ替える
static const std::unordered_map<char, std::string> LOCALE_VALUES({{'1', "ja-JP"}, {'2', "en-GB"}, {'3', "de-DE"},{'4', "en-US"}});

2.4 AVSのSDKをビルド
まずはcmakeを走らせます。
ウェイクワードをONやgstreamer許可なのをオプションとして設定しています。

cd /home/pi/sdk-folder/sdk-build && cmake /home/pi/sdk-folder/sdk-source/avs-device-sdk -DSENSORY_KEY_WORD_DETECTOR=ON -DSENSORY_KEY_WORD_DETECTOR_LIB_PATH=/home/pi/sdk-folder/third-party/alexa-rpi/lib/libsnsr.a -DSENSORY_KEY_WORD_DETECTOR_INCLUDE_DIR=/home/pi/sdk-folder/third-party/alexa-rpi/include -DGSTREAMER_MEDIA_PLAYER=ON -DPORTAUDIO=ON -DPORTAUDIO_LIB_PATH=/home/pi/sdk-folder/third-party/portaudio/lib/.libs/libportaudio.a -DPORTAUDIO_INCLUDE_DIR=/home/pi/sdk-folder/third-party/portaudio/include

そしてmake
make SampleApp -j3

makeのjオプションは並行処理の数で多い方がより高速になるがリスクもあるので、とりあえず3程度で。安全なのはもちろんjオプションなし。

3. AVSの認証
3.1 プロダクトの登録
amazonへサインインして今回のプロダクトを登録します。
入力方法はこちらを参考に(https://github.com/alexa/alexa-avs-sample-app/wiki/Create-Security-Profile)

この登録で設定したProductID,ClientID,ClientSecretの3つは認証時に必ず必要になるよ!

3.2 AlexaClientSDKConfig.jsonの設定
これは認証実行時に必要な情報を定義する設定ファイルです

場所:/home/pi/sdk-folder/sdk-build/Integration
ファイル名:AlexaClientSDKConfig.json

AlexaClientConfig.json
{
    "authDelegate":{
        "clientSecret”:”Amazonへ設定したClientSecret”,
        "deviceSerialNumber":"123456,(適当でいい)
        "refreshToken”:”{デフォルトの状態にしておく、認証後に自動的に追加されるため}”,
        "clientId”:”Amazonへ設定したclientID”,
        "productId”:”Amazonへ設定したproductID”
    },
    "alertsCapabilityAgent":{
        "databaseFilePath":"/home/pi/sdk-folder/application-necessities/alerts.db",
        "alarmSoundFilePath":"/home/pi/sdk-folder/application-necessities/sound-files/med_system_alerts_melodic_01._TTH_.mp3",
        "alarmShortSoundFilePath":"/home/pi/sdk-folder/application-necessities/sound-files/med_system_alerts_melodic_01_short._TTH_.wav",
        "timerSoundFilePath":"/home/pi/sdk-folder/application-necessities/sound-files/med_system_alerts_melodic_02._TTH_.mp3",
        "timerShortSoundFilePath":"/home/pi/sdk-folder/application-necessities/sound-files/med_system_alerts_melodic_02_short._TTH_.wav"
    },
    "settings":{
        "databaseFilePath":"/home/pi/sdk-folder/application-necessities/settings.db",
        "defaultAVSClientSettings":{
            "locale":"ja-JP"
        }
    },
    "certifiedSender":{
        "databaseFilePath":"/home/pi/sdk-folder/application-necessities/certifiedSender.db
    }
}

3.3 認証
認証用プログラムを起動、3000ポートで待ち受けます
cd /home/pi/sdk-folder/sdk-build && python AuthServer/AuthServer.py

ブラウザを立ち上げhttp://localhost:3000へアクセス
Developer用のアカウントを聞かれるのでログイン
ログインが成功するとWindowを閉じろというメッセージが出て認証完了

※AlexaClientSDKConfig.jsonのrefreshTokenに新たなトークンが追加されていることが確認できます。

4 実行
4.1 マイクのテスト
テストの前にpiのカレントに設定ファイルを用意します。

ファイル名:.asoundrc
場所:ユーザーカレントディレクトリ

.asoundrc
pcm.!default{
    type asym
    playback.pcm {
        type plug
        slave.pcm "hw:0,0"
    }
    capture.pcm {
        type plug
        slave.pcm "hw:1,0"
    }
}

※playbackは再生、captureは入力の設定ブロックになっている。
slave.pcmの値hw:はa,b a=カード b=デバイス番号となっている。
ラズパイに差したスピーカーとマイクの値を確認し設定すること。
aplay -lで確認できる。

4.2 soxのインストール
音声の加工や編集が出来るコマンドですー。
sudo apt-get install sox -y

4.3 マイクとスピーカーの入出力テスト
rec test.wav

実行したら何か話してみよう。
声に合わせて入力ボリュームが変化している様子がコマンドから分かると思う。
それが確認できたらControl+Cで終了

`aplay /usr/share/sounds/alsa/Front_Center.wav’

「フロントセンタ〜」っていう女性の声が聞こえたらOK
もし聞こえない場合はスピーカーの接続種別により次の設定を行って下さい

sudo amixer cset numid=3 x

xは接続の種類です。
0:自動判別
1:ライン入力(3.5mm)
2:HDMI
自動判別の場合はHDMIが優先されます。

4.4 いよいよAlexa起動
srcに移動
cd /home/pi/sdk-folder/sdk-build/SampleApp/src
SampleAPPを起動

TZ=UTC ./SampleApp /home/pi/sdk-folder/sdk-build/Integration/AlexaClientSDKConfig.json /home/pi/sdk-folder/third-party/alexa-rpi/models

SampleAPPの引数に設定ファイルであるAlexaClientSDKConfig.jsonとmodelsを指定

4.5 「Alexa! こんにちは!」と話しかけてみよう。
あとは、スマホにAlexa APPを追加するかここから好きなスキルを追加してみましょう。

カスタムスキルの作り方(Alexa Skills KitとLambda)はいろんな人が書いてるのでそちらを見てください。

続きを読む

Alexa Skills Kit が日本語に対応したので早速試してみる

Amazon Echoの日本語版がついに正式発表されましたね!
わたしも早速招待メールのリクエストを行いました。楽しみです。

Amazon Developer Consoleにも Japanese が追加されており、日本語のスキル開発が可能になっていました。
同時にコンソールやドキュメント類も日本語化されています。やったぜ!
https://developer.amazon.com/ja/docs/ask-overviews/build-skills-with-the-alexa-skills-kit.html

Alexaスキルの作成

スキル情報

日本語が設定できます!
今回はコンソール上でテストするだけなので、Invocation name等は適当です。

image.png

対話モデル

インテントスキーマの設定自体は日本語になっても特にかわらないかと思います。
日本人の名前、都市名、都道府県名など日本語に対応したBuilt in Slotも追加されています!
https://developer.amazon.com/ja/docs/custom-skills/slot-type-reference.html#list-types
これまでカスタムスロットで無理やり都道府県を定義したりしていましたが、そんなのは不要ですね。

重要なのはサンプル発話(Sample Uttarance)ですね!
ユーザの発話によってどのインテントを処理させるかAlexaが判断する元になります。
今回会社の同僚が作ってくれた近隣のラーメン店を検索するスキルを使用したので、以下のように設定してみました。

image.png

設定

エンドポイントの設定もこれまでと変わらないかと思います。
「デフォルト」にはスキルを実行するLambdaファンクションのARNを指定します。
English開発のときはバージニア北部にデプロイしなければいけないのが注意点でしたが、
今回は東京リージョンにデプロイして、そのARNを指定しました。

テスト

早速サービスシュミレーターでテストしてみます。
日本語で発話を入力し、スキルを呼び出すとAlexaが見事に適切なインテントリクエストを投げてくれました。
ロケールも ja-JP になっています。
聞くボタンを押すと、SSMLの結果も自然な日本語で読み上げてくれます。感動!

image.png

最後に

実機確認としてAmazon Fireで試してみようと思いましたが、恐らく言語設定の問題で
今のところは日本語を認識してくれませんでした。
早速試してみた内容をお伝えしました。参考になれば幸いです。

続きを読む

GitリポジトリとしてAWS CodeCommitを使う

Gitでソース管理をするにあたって、AWSにも CodeCommit というGitリポジトリを作れるサービスがあります。実際にリポジトリを作ってsshで接続できるようにするまでのメモです。

AWS CodeCommit

AWS CodeCommit は、完全マネージド型ソースコントロールサービスで、安全で非常にスケーラブルなプライベート Git リポジトリを簡単にホスティングできます。
Amazon CodeCommit(安全でスケーラブルなマネージド型ソースコントロールサービス) | AWS

料金

アクティブユーザが5人まで

  • 無料
  • 特典
    • 無制限のリポジトリ
    • 50 GB のストレージ/月
    • 10,000 回 のGitリクエスト/月

アクティブユーザが6人以上

  • 1 USD/月
  • 特典
    • 無制限のリポジトリ
    • アクティブユーザーごとに 10 GB のストレージ/月
    • アクティブユーザーごとに 2000 回 の Git リクエスト/月

つまり、個人で作ったコードを管理する分には、ほぼ無料の範囲内で利用できます。月に10,000回もgitリクエストを投げることは無いと思うので..。

仮に10,000回を超えたとしても、0.001 USD/Gitリクエスト なので大した料金にはならないでしょう。
ストレージについても、超過分については 0.06 USD/GB となっています。

類似サービスとの比較

類似のGitホスティングサービスとしては、Web上で利用できる GitHub や、サーバにインストールして使用する Gogs などがありますが、それらとの比較を簡単に書きます。(個人で使用する前提です)

  • 料金がほぼ無料(GitHubはプライベートリポジトリを作成する場合 $7/月)
  • 導入が簡単(GitHubは説明がEnglish、Gogsはサーバ(PC)へのインストールが必要)
  • プルリクエスト機能がない(GitHub、Gogs共に有り)

この他、Commit履歴の可視化や、タグ・ブランチの管理など、基本的な操作はGUIでできます。

AWS特有の機能としては、ブランチへのpushなどのイベントをトリガーとして、アラートを飛ばしたり、Lambda関数を実行できたりします。

リポジトリを作成してssh接続できるようにするまでの手順

sc 2017-09-21 14.02.22.png
今すぐ始める をクリック。

sc 2017-09-21 14.02.27.png

リポジトリ名 と 説明 を入力して リポジトリの作成 をクリック。

sc 2017-09-21 14.03.31.png

これでリポジトリが作成されました。
次の画面ではhttpssshそれぞれでの接続方法が書かれているので、この通りに準備をしていきます。

まず、ssh接続用のキーペアを生成します。既にキーペアを持っている場合は、新たに生成する必要はありません。
ここからはターミナルでの操作になります。(Macでの例です)

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/Users/hogehoge/.ssh/id_rsa): /Users/hogehoge/.ssh/codecommit_rsa  ;;;任意のパス、名前を指定します
Enter passphrase (empty for no passphrase): ;;;任意のパスフレーズを入力します
Enter same passphrase again: ;;;任意のパスフレーズを再度入力します
Your identification has been saved in /Users/hogehoge/.ssh/codecommit_rsa.
Your public key has been saved in /Users/hogehoge/.ssh/codecommit_rsa.pub.
The key fingerprint is:
SHA256:Ha6ETkhmC7muDZmmxzZk8DgRi7XZMpMU8khj4f3qzuQ hogehoge@HOGEHOGE.local
The key's randomart image is:
+---[RSA 2048]----+
|  o .+oo         |
| ..o..+. o       |
|.B.++ ..*        |
|O E..= + .       |
|.X... o S        |
|+. +   o         |
| .B +   .        |
|.o =oo           |
| .++ooo.         |
+----[SHA256]-----+

これでキーペアが生成されるので、パブリックキーの値をコピーします。

$ cat ~/.ssh/codecommit_rsa.pub
ssh-rsa AAAAB3NzaCino3r4aa2GpYkIpjzJAOOO8VcZw6eYfJr9RmdDNMS2/qcEk1yc2EAAAADAQABAAABAQDe0jBpJOHTSGuWRLmJT3s7RwGXw3rV56D4BDOasaCz24m3HxA8oXtRLsUZmiAf+LODBpoLPxWuBKfH/n1aseCByrmHV3FXhAHqH2v33EgrEeYm07xB1RifJHn5oXfCDpssfKVGd25FBslDgzjBElDjA+BRRGVI3lkitl2su19AtGa9b/jzj6UtdAc7msuR5ZM+MP/8jnq2zuc2YtMopt/YXdMAYuo1T0y6atVDmCqirSXE0+ITezFwzIEiximRkQHtO2B4CzJE9LF6kSD5RfLY9r0XHWcc+RpuO+QlD hogehoge@HOGEHOGE.local

AWS マネジメントコンソールに戻って、IAMの画面を表示します。
既存(または新規)のIAMユーザに対して、CodeCommitへのSSH接続キーを設定します。

IAM > ユーザー > {ユーザ選択} > 認証情報
sc 2017-09-21 14.19.34.png

sc 2017-09-21 14.19.40.png

先ほどコピーした ~/.ssh/codecommit_rsa.pub の内容を貼り付けて、SSH公開キーのアップロード をクリックします。

sc 2017-09-21 14.42.22.png

すると、赤枠の部分に SSHキーIDが表示されているので、これをコピーします。

ここから、再度ターミナルでの作業になります。

$ vi ~/.ssh/config 
Host git-codecommit.*.amazonaws.com
        User AAAAAAAAAAAAAA ;;;コピーした SSHキーID を記載
        IdentityFile ~/.ssh/codecommit_rsa ;;;先ほど生成したプライベートキーへのパス

ここまでで、sshの設定は完了です。
あとはpushするなりpullするなりcloneするなり、普段通りGitコマンドを叩いてください。

続きを読む