この記事は個人開発サービスに用いられている技術 Advent Calendar 2018 の22日目です。
こんにちは、2z(Twitter: @2zn01 )です。
普段は会社員でWeb系の開発エンジニアとして働き、週末に趣味で個人開発をしています。
今年の7月に話題のAIをweb上で誰でも気軽に作れる「AIメーカー」というサービスをリリースしました!
■AIメーカー
https://aimaker.io/
この記事では、この「AIメーカー」で使っている技術をまとめたいと思います。
以下の3ステップで誰でも簡単にAIを作れます!
今話題のAIをweb上で誰でも気軽に作れる「AIメーカー」を開発しました!①AIに覚えさせたいタグを入力②タグから自動で画像データを収集③AIがデータから学習の3ステップで誰でも簡単にAIを作れます!動画では手相占いのAIに挑戦!みんなもAIを作って遊んでみてね!https://t.co/66DFU7GRZ2 pic.twitter.com/ie1LmioyA1
— 2z@AIメーカー (@2zn01) 2018年7月19日
学習データを各ラベル名から自動で収集する機能を実装!これはなんとAidemyの石川さん(@ai_aidemy)よりアドバイス頂いたアイディアです!大感謝!!僕も最近始めたところですが、Aidemyは機械学習、ブロックチェーンなど最新の技術も勉強できておすすめです!https://t.co/gORhd5P7Ls#AIメーカー pic.twitter.com/2cNpjzjPAl
— 2z / AIメーカー開発 (@2zn01) 2018年7月8日
複数AIのモデル学習を並列で走らせる対応も無事完了!(処理の裏側では複数のGPUサーバが走っている)学習には時間がかかってしまうため、エポック数(訓練データを何回繰り返して学習させるか)は500に調整し、10分以内には終わるように。精度よく学習させたい人は応相談にしておこう#AIメーカー pic.twitter.com/ukM3sg9rNG
— 2z / AIメーカー開発 (@2zn01) 2018年7月7日
学習履歴を一覧表示して、グラフを切り替えれるようにしてみた。#AIメーカー pic.twitter.com/wxcxZ3HXLE
— 2z / AIメーカー開発 (@2zn01) 2018年7月8日
AIメーカーの診断結果へ無駄にグラフを追加してみた!#AIメーカー pic.twitter.com/YCTaBDawhh
— 2z / AIメーカー開発 (@2zn01) 2018年7月14日
AIメーカーのシステム構成図は以下の通りです。
大きな構成としては、主にユーザからの様々なリクエストを受け付けるフロントサーバと機械学習の処理を取り扱うバックエンドサーバの2つがあります。
クラウドのホスティングは、Amazon Web Services(以下、AWS)をメインで使用しており、Amazon EC2でサーバを立てています。
サーバのOSはLinuxでAmazon Linux 2を使っています。
AWSがメインですが、文字起こし機能の方ではGoogle Cloud Platformで、Google Compute Engine(GCE)でサーバを立てています。
サーバのOSはLinuxでCentOSの7系を使っています。
なぜAWSの他にGCPも使っているかというと、文字起こし機能の方でGoogle Cloud Vision APIやGoogle Cloud Speech APIを使っており、大容量の音声ファイルや画像ファイルを取扱うのにGoogle Cloud Storage経由で使った方が都合がいいからというのが理由になります。
webサーバはApacheを使っています。
Nginxもありますが、Apacheは普段から使っており、設定も把握していたため、いつも通りの安定の選択としました。
Amazon RDSを使ってMySQLを立てています。
複数のインスタンスで学習データや学習済みモデルを共有できるようにAWSのAmazon EFSというネットワークファイルシステムを使っています。
AIメーカーではフロントサーバとバックエンドサーバで分かれており、そこの連携が肝になってきます。
そこでAmazon EFSを使うことで、全インスタンスで同じファイルを共有することができるので、めんどいことを考えなくてもよくなります。
サーバをスケールさせる際に問題となってくるのがデータが格納されるDBとファイルになるかと思います。
Amazon EFSを使うことでファイルの読み込みや書き込みの速度は犠牲になるため、ユースケース次第かと思いますが、この辺の問題を考えなくてもよくなります。
ただ、ストレージ料金が高いのが悩みの種です。。><
フロントサーバ側のプログラムはPHPを使って実装しました。
フレームワークはZend Frameworkを使用しています。
バックエンドサーバ側のプログラムはPythonを使って実装しました。
フレームワークはFlaskを使用しています。
Deep LearningのフレームワークはCaffeを使用しています。
クライアント側のJavaScriptは、jQueryを使って実装しました。
AIメーカーを作るにあたって、一般的なwebサービスにはない機能をどう実装しているかをご紹介します。
主に以下の機能について、まとめてみます。
ディープラーニングで画像分類のモデルを作る際には、AIにこの画像は〇〇であるということを教えるため、学習データにラベル付けを行います。
この学習データのラベル付けは、モデルの精度に大きく影響する重要な作業ですが、単調な作業なためにとても退屈です。
そこで、AIメーカーでは事前に登録していたラベル名から画像データを自動で収集する機能を用意いたしました。
ちなみにこちらの機能はAidemyの石川さんよりアドバイス頂いた機能です。大感謝!
学習データを各ラベル名から自動で収集する機能を実装!これはなんとAidemyの石川さん(@ai_aidemy)よりアドバイス頂いたアイディアです!大感謝!!僕も最近始めたところですが、Aidemyは機械学習、ブロックチェーンなど最新の技術も勉強できておすすめです!https://t.co/gORhd5P7Ls#AIメーカー pic.twitter.com/2cNpjzjPAl
— 2z / AIメーカー開発 (@2zn01) 2018年7月8日
ラベル名からの画像データの収集は、Bing Image Search APIを使用しています。
一つのラベルごとに50件の画像データを収集するようにしています。
この学習データの収集はブラウザからAjax通信でリクエストを投げ、サーバ側でバックグラウンドで処理させています。
処理時間はラベル数によりますが、少なくとも数分はかかるので、単純にリクエストを投げて応答を待っていると通信がタイムアウトしてしまう可能性があります。
そこで、サーバ側にリクエストを投げたら一度データベースへその処理をタスクとして保存しておき、一旦ブラウザ側へレスポンスを返しています。
サーバの裏側では常にデーモンが監視(待機)しているので、データベースへ学習データの収集タスクが登録されたら、収集処理が開始されるようになっています。
また、ブラウザ側では定期的にその進捗状況をAjax通信で見に行く(ポーリングする)ようにしています。
なお、AIメーカーでは手軽に利用できるように学習データの自動収集機能は用意しておりますが、それだけだと質の良い学習データは用意できないため、JPG、PNG、ZIPによる画像データのアップロードにももちろん対応しています。
モデルの学習といえば、AIメーカーの根幹の機能になります。登録された学習データをもとにモデルを学習させます。
先のシステム構成図で示しましたが、AIメーカーにはフロントサーバとバックエンドサーバがあり、モデルの学習はバックエンドサーバで行います。
具体的には以下の流れで行います。
1. フロントサーバ側で学習データに不足がないかチェック
2. フロントサーバ側でCaffeで学習を開始するのに必要なファイルを生成する
3. フロントサーバ側からAmazon EC2のGPUインスタンス(バックエンドサーバ)を起動する
4. インスタンスの起動後、セットアップスクリプトを実行(具体的には以下のことをやっています)
5. バックエンドサーバへの疎通確認後、フロントサーバからバックエンドサーバへCaffeの学習開始のリクエストを投げる
6. バックエンドサーバ側でリクエストを受け、Caffeの学習コマンドを実行する
convert_imageset -resize_height=227 -resize_width=227 -shuffle / {学習データのリストファイル} train_lmdb
convert_imageset -resize_height=227 -resize_width=227 -shuffle / {テストデータのリストファイル} test_lmdb
compute_image_mean train_lmdb mean.binaryproto
compute_image_mean test_lmdb test_mean.binaryproto
caffe train -solver=solver.prototxt -weights {モデル} 2>&1 | tee {学習ログファイル} &")
7. フロントエンドサーバ側で学習ログファイルから進捗状況を把握し、学習状況をグラフで表示
学習ログファイルはAmazon EFSで共有しているので、そのログの中から正規表現でせっせと該当値を抽出します
if (preg_match('@] Test net output #0: accuracy = ([0-9.e\-]+)@', $record[$i], $matches)) {
$accuracy = rtrim(rtrim(sprintf('%F', $matches[1]), '0'), '.');
}
if (preg_match('@] Test net output #1: loss = ([0-9.e\-]+)@', $record[$i], $matches)) {
$loss_test = rtrim(rtrim(sprintf('%F', $matches[1]), '0'), '.');
}
if (preg_match('@] Iteration [0-9]+, loss = ([0-9.e\-]+)@', $record[$i], $matches)) {
$loss_train = rtrim(rtrim(sprintf('%F', $matches[1]), '0'), '.');
}
8. 学習完了後、バックエンドサーバ側でモデルが生成される
9. フロントサーバ側でログから学習完了を検知し、学習結果をデータベースへ保存し、EC2インスタンスを停止する
以上が処理の流れになります。
学習が完了し、生成されたモデルを使って画像分類の推論を行う機能です。
こちらは以下の処理で行っています。
1. ユーザーさんが推論したい画像をブラウザからアップロード
2. フロントサーバで画像データを保存し、バックエンドサーバへ画像ファイルパスをパラメータに推論のリクエストを投げる
3. バックエンドサーバでリクエストを受け、Caffeで推論処理を実行し、結果をJSON形式で返す
4. フロントサーバでレスポンスを受け取り、推論結果をグラフで表示する
今回、特にAIメーカー特有の機能に絞って、実装方法をまとめてみました。
AIメーカーではフロントサーバとバックエンドサーバの複数インスタンスで構成し、それぞれを連携させて実現している箇所が多いため、多少複雑になっています。
実際に作ってるときは頭の中でシステム構成をイメージして実装を進めていますが、後で見返すとどうだったっけな?となることがほとんどです。
このへんはきちんとメモするか、図解するかしてきちんと残しておいた方がよさそうですね。
なお、AIメーカーでは誰もが手軽にシンプルに使えること、そして学習が早く終わるようにするため、現時点ではモデルの精度を犠牲にしています。
そのため、今後は精度向上のために学習の際のハイパーパラメータのチューニングをしたいとか、学習の回数をもっと増やしたいとかなどの要望に応えられるようにする必要があると感じています。
学習自体はサーバ側でGPUを使ってやってます。ただ、まずは手軽に利用できるように学習時間を大幅に削減するべく、本来もっと学習すべきエポック数を少なくしてるので、精度はそんなに出ないのが現状です。こちら、精度を上げたい方はオプションでパラメータ調整を可能にしたり等、今後の課題です! https://t.co/ZNfOUGxtS9
— 2z / AIメーカー開発 (@2zn01) 2018年7月21日
今後、このあたりの機能拡張も行っていきたいと思います。
この記事に少しでも興味をもって頂けましたら、ブログの読者登録やTwitter: @2zn01をフォローして頂くと更新の励みになります!
皆さんもぜひ自分のサービスを作っていきましょう!
中学~大学でガラケー向けサービスで1億PV超えを達成するもドメイン失効でふっとばす。 web上で誰でも手軽に機械学習を始められるプラットフォーム 「AIメーカー」を開発 → https://aimaker.io/ 話題のツイートがジャンルごとに探せる「ツイレポ」も → https://twirepo.com/
Crieitは誰でも投稿できるサービスです。 是非記事の投稿をお願いします。どんな軽い内容でも投稿できます。
また、「こんな記事が読みたいけど見つからない!」という方は是非記事投稿リクエストボードへ!
こじんまりと作業ログやメモ、進捗を書き残しておきたい方はボード機能をご利用ください。
ボードとは?
コメント