1対nの関係をどう把握して運用するか

久保隆宏氏(以下、久保):というわけでまとめると、まずモデルがいろんなところで使われて1対nになる可能性がある。まずこの1対nの関係というのを把握しないといけない。同じデータソースが出自のモデル間で判断が割れないように同期更新をする必要がある。

これらをどうやって把握して運用するが問題になってると言えると思います。

じゃあどうするか? これには開発面と運用面からのアプローチが考えられます。開発面というのは、簡単に言うとコードにおけるモジュール依存関係の文脈でこれらの依存を管理するというかたちです。

運用面からのアプローチというのは、学習プロセスとか機械学習にまつわる処理っていろいろログが出るんですけど、そのログをきっちり管理しておくことで依存関係をたどるというような方法です。これらは別に対立するわけじゃないので、併用することが可能です。

まずコードからのアプローチですね。モデルの利用とかデータの使用というのはいずれもコード上の依存関係で表現することが可能です。

例えばデータセットだったら、データセット用のモデルを作って、クラスに対してその学習を使うようにすると、これはソースコード上のモジュール依存関係になるとどのモデル中に、つまりこのモデルではどのデータが使われているかという依存関係を可視化するようなツールを作って追随することができます。

閾値の場合も同様です。閾値を作成する際にどのモデルを使ったのか。そのモデルの閾値は、どのAPIで使われているのかということをコード上できちんと明記しておきます。

APIを使うときはこういうかたちです。

モデルと閾値が併せてAPIとして機能するというかたちにしなくてはいけない。ちなみにこれは画面コードなので正確じゃないですけど。

こういうようなかたちにして、どのモデルとどのモデルが依存関係にあるのかをコード上で表現するのがこの開発面からのアプローチです。

運用面からのアプローチ

運用面からのアプローチとしては、最近Cloud MLとか、今日のハンズオンではAmazon Sage Makerのことをやっていると思います。機械学習の学習プロセスをサポートしてくれるサービスがいろいろあります。

これらを使うと、機械学習にまつわるプロセスのログを残すことができるんですね。このログには学習時に指定したパラメーターやデータその他もろもろを記録することができるので、こいつを使っておくと「このメールにはこのデータを使って」っていうことが把握できる。ただモデル間の依存関係はこれだと難しいですけど。

開発面からのアプローチというのは、もう使ってほしくないデータにはDeprecated Warningをつけるとかですね。

あるモデル専用に作ったモデルだから、意図せずにほかのモデルで使われることを防止したいときに例外を飛ばすとか。そういうコード上のチェックをそのまま使えるので、そのメリットが開発面からのアプローチにはありますね。

運用面からのアプローチについては機械学習モデルの学習とかデプロイにまつわるログを残すこと。依存関係の問題だけじゃなくて機械学習全般で管理しないといけないことなので、どのみち導入を検討したり、なんらかの仕組みを検討しないといけないという話になってきます。なのでその中でやれば特段の追加コストもなく対応することができると。

ただログベースになってしまうので、そもそもどうあるべきだったのかという管理ができない。最初にもあった通り、これらは対立する対策ではないので併用することも可能です。これだけ言うとかなりコンサルタントみたいな感じになっちゃうので、実際にやってみました。

コード上でデータのモデル間の依存関係を表現したいとすると。あとはクラウド上での実行を可能にしてログを残すということですね。メインとしてはこういうかたちで、今回はGCTを使っているんですけど。データはGCSというところに格納する。

前処理についてはGoogleのCloud DataFlowを使います。これはApache Beamでサポートされているので、そこで処理を実装することができます。機械学習モデルは満を持して登場したGoogle Cloud Machine Learningです。

実装はscikit-learnのPipelineっていう仕組みなんですけど、それをベースに実装して、モデル以外の部分はApache Beam、Cloud Data Flowに流して、モデルの学習についてはCloudMLっていう計画で開発を進めました。

ただ1個だけ問題があって。真ん中のやつがPython2のみしか対応してないっていう。なのでApache Beamはちょっとさよならするしかない。ただ、これは対応中なので、上期中にはたぶん対応終わるんじゃないかと思ってます。

依存性をコードで表現しても万事解決ではない

というわけで、現行の構成はこういう感じです。(スライドを指して)ちなみにGoogle Cloud Machine Learning上でも別に前処理できないわけじゃない。データがGCSで接続して前処理も含めた機械学習モデルを構築プロセスがGoogle Cloud Machine Learningに投げるというようなかたちでやっています。

ローカルでもクラウドでもいろんな形式でコードを書いて。スライドだと見えにくいんですけど、ほぼ同じコード。学習のコードはまったく同じものがlocalでもcloud MLでも回すことができると。

ただクラウド上で学習するときはオンクラウドを設定するというふうにするだけでOKにしています。あと、リージョンを指定しないといけないので指定してるんですけど。これによってlocalのコードでは当然依存関係というのが表現されていて、なおかつcloud上で実行すれば、完璧だという話になる。

しかしやっぱり現実はそう甘くないことがいろいろあってですね。コード上で依存関係を表現すること自体は別段難しくないんです。このデータを使って学習する、このモデルを使って学習する、と。

ただ、コードに書いちゃうっていうのは、実行と表裏一体で、素直にやっていくと学習のたびに毎回依存性に沿った更新が行われちゃうんですよね。さっきの例だと、解約防止のモデルを作った瞬間に閾値の更新も走り、さらに解約防止理由を考えたモデルも作るとか。

依存関係をコード上で表現することは可能なんですけど、コードがあるというのはそれは実行するということなので。毎回毎回依存性に基づいた実行をされると困るわけですね。このへんについては、まだ実装は済んでないんですけど、開発・本番以外にステージングっていうステータスを設けてやろうかなと考えています。

機械学習エンジニアの気持ちとしては、学習を何回もやりたいわけですね。気軽に。学習を何回もして、「よし、これでまあまあだろう」となったらステージングにあげる。依存先のモジュールは常にステージングを見ると。

デプロイをするときに初めて「依存先の各モデルが全員ステージングに揃っているか?」「よし、全員揃ってるんだったらいくぞ!」というふうにして、リリースを行うのがいいんじゃないかと考えています。

ログのネーミングルール、バージョンの管理はやはり大切

あとは細かい話になってくるんですけど、クラウドストレージ上のファイルって、Gitとかのバージョン管理されるものと違って簡単に上書きされるんです。学習時のソースも学習モデルさえもどんどん上書きされちゃうんですよ。

なので「よし!」と思ったモデルがいつの間にか誰かが学習を実行した瞬間に上書きされるとかですね。そういうことが往々にして起こり得るわけです。だから適切なネーミングルールで運用しないといけない。

あと、ログが残るというのもバラ色な話ではなくて。ログは残っても、ログとモデルの紐付けって自前で行わないといけないんですね。ログは残っているものの、「このモデルの学習に使ったJOBってどれだっけ?」とか「このモデルファイル、チェックポイントファイルを作ったときのソースはどれだっけ?」という話になって。

管理してないと、ログが残っていてもそのログがどこで使えたのかわからないっていう話になってきちゃうんですね。ネーミングでカバーをするという話になってくる。なので、コーディング以外に各種ファイルのどのフォルダにどういうネーミングルールの何を納めるのかを決めておかないといけません。さらに決めた上で、チェックしないと上書きとかしちゃうのでチェック機能も合わせてネーミングルールを定めないといけない。それがけっこう面倒くさいところです。

あとデータについては、バージョン管理もけっこう重要です。再学習のタイミングを把握するのに重要になってきます。モデルが学習したときのデータと現実のデータがずれてくるのが再学習のタイミングなので。学習したときのデータというのは残しておかないと、いつ再学習すればいいかというのがわからなくなっちゃう。

人間が気づくかもしれませんが、人間が気づいたときにはもう遅いので。これはデータの静的チェックっていうんですけど。そういうことをやるためにもデータのバージョン管理が必要になります。

あと今回GCPだいぶ触りました。GCPの仕様についていろいろあるんですけど、これはちょっと話すと長くなるのでカットします。今回作ったツールは今後開発で使っていくので、その中でどんどんブラッシュアップしていってちゃんと使えるようになったらそのときに話そうかなと思います。

というわけで機械学習モデルを利用するメリットと、そこで生まれる課題とその解決方法についてお話ししました。ここからは今度どうなるかというのと、今日はなぜこういう話をしたのかを話していきます。

機械学習の活躍する範囲について

今日のまとめです。機械学習の活用が進んでいるなかで、機械学習の判断というのは確率的なのでどちらかに寄せないといけない。寄せる処理というも合わせて更新しないといけないですよと。それによって依存関係が生まれる。この依存性を管理するには開発面と運用面のアプローチがあります。

今日の話は、わりと再学習が頻繁にあるケースを想定しています。ある判断だけに特化していてデータの傾向はほぼ変わらないようなケースは、今日お話ししたような問題はあんまり問題になりません。

つまりこういうことですね。

データの変動が大きくて再学習が頻繁に必要である、なおかつわりと汎用的な判断をする。

特化した判断というのは1回作っちゃえば実現可能になるので。あとデータの変動が少なかったら、別にそもそも再学習をする必要がなかったり。

現在機械学習が活躍している領域というのは主にこんな(スライドを指して)領域というのが個人的なイメージです。

具体的な事例をはめ込むとこういう感じです。

画像認識でキューリができたとか、タイトルがあるとか、パンとか餃子とかピザとかいろんなものをみんな認識しているんですけど。

ピザって、2020年を超えた瞬間にピザという概念が変わって丸じゃなくて四角になるとか、そういうことはあんまないですよね。データの変動がわりと少ない領域ですごく力を発揮しているわけです。

汎用性の高いデータというのは、イメージネットとかウィキペディアみたいな、変わりはするけれどそんなにドラスティックに変わったりしないデータ。それをもとにいろんな機械学習のサービスが公開されていると。

あと、データの変容が少し大きめのところだと、異常検知とかそういうのがあると思っています。

現在、機械学習の活用が進んでいる領域で、今回のような問題が起こることはわりとレアなケースだと思います。しかし、今こうやって機械学習が活用されている領域ってそのうち自動化されるかな、というのが個人的な感覚としてあります。

機械学習の領域も自動化される未来?

今はまだ簡単とはいえコードで書かないといけないですけど、いずれ機械学習の知識がまったくないような人でも簡単に扱えるようなサービスというのが登場するのではないかと思います。

まあもう登場してるんですけど。こいつが登場するとどうなるかと言うと、機械学習エンジニア自身がAIにとってかわられる可能性がある領域というのはこれくらいあると(スライドを指して)見込んでいます。

そうなると消え去るという話で、今ディープラーニングとかデータサイエンティスト養成講座ってたくさんやってますけど、あれは生まれた瞬間に死ぬしかない時代がもう目の前に来ているというのが、個人的な今後ですね。

「自動でできるものってたかがしれてるんでしょ」ってみなさん思うかもしれないんですけど。これは今もっとも熱い研究テーマの領域です。人間が構築するよりいい精度を出す技術がけっこう出てきているというのが現状です。

自動構築が可能ということは、データの変動にも強くなります。データが変わったと思ったらモデルベースから自動で構築すればいいだけなので。つまり精度的にも柔軟性的にもけっこう高いレベルに達する可能性がある。

とくにデータの変容が少ない場合はやりやすいですね。データが少なかったら難しいんじゃない? って話になるんですけど、データが少なかったらどのみち人間がやったって難しいので。これはあまり差別化要素にはならない。

あとデータにあった構造を自分で探索できるので柔軟性が非常に高い。つまりあの(スライドの)灰色の部分は全員死ぬしかないという話になると。ただ自動構築モデルというのはわりと汎用的な、さっき言ったイメージネットやウィキペディアをベースにしたモデルから学習されるので、そこからでは届かない領域というのは右上のほうにはあるでしょう。

汎用性が高くなるほど汎用的なデータと傾向が似てくるので、そういう意味では汎用性が高い判断というのは自動化でも行えると思います。

機械学習エンジニアの役割は「より特化、より汎用化、より柔軟」に

なので今後機械学習エンジニアが果たす役割というのは、この3つの領域になってくるのかなと思っています。

1つはより特化したモデルを作るという話。あと、より汎用的なモデルを作ること。あと自社用のベースモデルをきちんと持って、普通の自動構築では対応できないレベルの自社にとっての変動データに、より素早く対応していく、というところがあるんじゃないかなと思っています。

より特化というのはデータの前処理とか、そもそも素のデータにはなかった特徴とかですね。このデータってほかのところから取ってくれば特徴つけられるんじゃないか。そういうデータに関する知見とかがより特化ですね。

よりドメインに特化した処理を行うことで精度を上げていくということで、イメージとしてはKaggleのコンペティションの領域にけっこう近いですね。

実際、Kaggleのコンペティションで上位チームのトリックとか見ると、わりと前処理とか特徴エンジニアリングの話がけっこう多い印象があります。なので、各ドメインにおける知識を磨くというのはまず1つ考えられる領域です。

より汎用っていうのは、細かいカテゴリーとか言語ではクロスリンガルなモデルというのが注目されているんですけど、より汎用性能の高いモデルを作るということですね。ちなみに汎用性であればあるほど柔軟性にもつながるというメリットもあります。

より柔軟というのは、事前学習済みモデルを駆使して少ないデータしかない状況にでも対応する。これも画像に限らず、自然言語処理の分野でも盛んに行われています。

実際のビジネスにおいても、環境っていきなり変わるんですね。変わったあとのデータってあんまり手に入らないわけです。例えば質問回答システムでいきなり法令が変更されたとか。新しい機種が出たとか。あとは画像からの異常検知モデルだと点検する場所が増えたとか、時間帯が変わったとか。

売上予測だと近くにいきなり競合店ができたとか、毎年開催されてたお祭りが中止になったとか。けっこうドラスティックで非連続的な変化が起こるのが我々が実際に生きているビジネス環境です。

変化が起きた直後のデータというのは、大量にはそうたやすく手に入らないわけです。そうなってくると、そういう状況でもモデルを活用したければ既存のモデルを活かして少ないデータで対応させてやろうと、おのずとそういう方向性になってくる。

つまり柔軟性というのは、変化が多い分野にも機械学習の活躍の場を広げるという面でも重要です。そのときに、今日お話しした課題というのが重要になります。

つまり、手にしやすい汎用的なモデルをデータ化して、さまざまな問題に対応していく人の話になったときに、ちょっと汎用的なモデルの関係性はいったいどうなっているか? とか。あるいは、いつ同期更新をすべきなのか? という話が問題になってくる。

なので、今後機械学習エンジニアが果たす役割において今日お話しした内容というのは問題になってくると考えています。機械学習自体の自動化が進む中で、機械学習エンジニアという人間が取り組むべき問題はどんどん変化してきていると思っています。今日ご紹介したのは「より特化、より汎用化、より柔軟」という3つです。

今後はもはや機械学習の問題にとどまらない

ちなみにこれは強制スクロール型の進行なので我々に拒否権があるわけじゃないんです。もう技術が出ちゃったらおしまいなので。

だからさっき言ったように、今まさに養成中のエンジニアも昔のスクロールゲームみたいに上からピューッと落ちてくるのと同じなんです。上からピューっと落ちた瞬間に強制スクロールなので、画面に挟まれてしまうと死ぬしかないという話になってきます。

そうならないために、自分たち自身で取り組むタスクというのが「本当にこれは人間がやらないといけないことなのか?」と常に問いかけていかないといけないし、自分たちが新しい領域にチャレンジしていくんだったらそこに応じた課題というのが含まれてくる。

逆に考えれば、すでに解決された問題については自動的に処理してくれるありがたい状況というポジティブシンキングの考えです。

データがなければ力が出ないというのが機械学習モデルの通説だったんですけど、実際学習済みモデルの活用によってけっこうこの前提は崩れてきています。GoogleのAutoMLなんてモデルは数枚の画像で認識が可能っていうものも出ています。

ただ我々が次に向かわないといけないステージは、ビジネス的にも有用でなおかつ研究的にもチャレンジングな感じです。つまり新しい領域に機械学習エンジニアが取り組むということ自体がビジネス的にも価値があるところにもつながっていくということです。

さっき言ったように、いきなりAutoMLとか、そういうものに対応していくには、機械学習エンジニア自身が挑戦する領域をどんどん前に進めていく必要があるということです。

この進歩には、単純に機械学習をやってる人だけじゃなく、エンジニアの人の力というのも非常に大きいと思っています。

今日お話ししたような課題はもはや機械学習の問題というより依存性管理の問題や、設計上の問題など、普通のエンジニアのみなさんが毎日抱えている問題と似通ったところがけっこう多いんですね。

なので、機械学習のエンジニア自身が新しい領域にチャレンジしていくということももちろんなんですが、アプリケーションエンジニアや一般的なエンジニア自身がそういった状況においてどういう管理が必要でどういう開発に取り組まないといけないのかを協調して考えていくことが今後必要になってくるのかと思います。

つまり機械学習の活用を次にステップに進めるためには、研究面だけではなくエンジニアリング面での進化も必要になってくるんじゃないかなと考えています。ということで、今日の話は終わりです。ご静聴ありがとうございました。

(会場拍手)