Flutter Meetup Tokyo #3 が開催されました

flutter03_00.JPG 技術企画グループの玉田です。

2018年7月19日(木)に DeNA TECH STUDIOにて Flutter Meetup Tokyo #3 の開催をサポートさせていただきましたので、その模様をレポートいたします。

Flutter Meetup Tokyo とは

Flutter Meetup Tokyo は東京で開催される Flutter にまつわることであれば何でも発表できる勉強会で、今回が3回目の開催となります。当日はライブ配信もあり、会場まで来ることが難しい参加者の方にも開かれたイベントとして開催されました。

各発表について

ここからは当日発表された内容を紹介していきます。

Flutter開発に役立つPlugin Package10選

flutter03_01_new.JPG

kuwapp さんに、Android, iOS のプラットフォーム固有の実装も含む「Plugin」と、プラットフォーム関係ないDartのライブラリ「Package」について、開発に役立つものを紹介いただきました。10選の中でもflutter_villains が簡易なアニメーションを作る際に便利そうかと思われました。

Flutter アプリを BLoC パターンでリファクタリングし、BLoC を DI してみた

flutter03_02.JPG TatsushiKiryuさんに、Bussiness Logic Component (BLoC)というビジネスロジックを分離するパターンをDependency Injection (DI)の仕組みで実装してみた結果を紹介いただきました。DI の仕組みについてはまだイマイチ感があり、今後に期待とのことでした。

Flutter vs ReactNative

flutter03_03.JPG slime_a さんに、Flutter と React Native を様々な観点で比較した内容について紹介いただきました。Google が開発しているだけあり、Flutter は処理が高速で公式情報が豊富、なおかつマテリアルデザインを主軸にしたUI開発ができることがメリットとのことでした。

Nativeリソースの利用

flutter03_04.JPG mirock さんに、Flutter から C++ で書いたNativeコードを利用する話をしていただきました。

Flutterからネイティブコード呼ぶ

flutter03_05.JPG shogo.yamada さんに、Flutter から Swift、Kotlinなどのネイティブコードを呼び出す方法についてお話しいただきました。Flutter だけでは実装できない処理についてネイティブで作った ViewController の呼び出し方、パラメーターの渡し方に絞った説明でした。

"Hello Flutter"の次におさえたい Flutterのポイント その5

flutter03_07.JPG Kenichi Kambara さんに、Flutter をつかった開発で抑えておきたいポイントについてお話しいただきました。Android や iOS 用の様々なアプリアイコンを、画像1つ用意すれば作成してもらえる flutterlaunchericons が便利そうかと思われました。

Hello Flutter"の次におさえたい Flutterのポイント その5 from Kenichi Kambara

Flutter ちょっとわからず 大慌て 理由が分ると あっけないのよ

flutter03_08.JPG aja_hiraiさんに、「作りたいレイアウト」をFlutter で実現しようとする際に、陥りやすい罠についてお話しいただきました。Flutter を使ってみようと思う人が真似できそうな Tips をいくつも共有いただけました。

Flutter x Firebase

flutter03_09.JPG NAYOSO (Niko) さんに、Flutter と Firebase を組み合わせた利用について紹介いただきました。特に Firebase Remote Config は 配信済みのアプリ内の設定を動的に変えることができ、ユーザーによっても設定を変えることができるのでABテストを行う際に使うと便利とのことでした。

プロトタイプ開発とFlutter

flutter03_10.JPG horie1024 さんに、Flutter と Firebase を使った VUI アプリのプロトタイプ開発について説明いただきました。Android エンジニアのスキルセットで両方のプラットフォームのプロトタイプ開発を行う際に、Flutter と Firebase を組み合わせて利用するのがとても簡単で良かったとのことでした。

明日から使えるFlutter for Android

flutter03_11.JPG hiraok さんに、Android の側面から見た簡単な機能の実装例について紹介いただきました。タブビュー、リスト、非同期通信、地図、画面遷移の5つを例にあげ、 簡単な機能ならネイティブに比べ少ないコード量で早く実装できたとのことでした。

おわりに

flutter03_06.JPG 他の勉強会に比べ、 Flutter これからみんなで使って盛り上げていこうぜ!という参加者の意気込みが大きいイベントだったかと思いました。 Flutter 未経験者にとってもわかりやすく、取り組み始めやすい発表が多かったので、初回から発表で参加もしやすいと思います。今回参加できなかった人は、次回は参加者としてはもちろん発表者としても参加してはどうでしょうか。

DeNAは世の中の技術向上に貢献する勉強会やイベントを積極的に支援するため、「DeNA TECH STUDIO」というエンジニアリングに関する勉強会サポートプログラムを運営しています。本イベントもこちらでサポートさせていただきました。こちらご興味ある方はぜひご確認下さい。

参考:DeNA TECH STUDIO

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

Amazon SageMaker ハンズオンレポート

はじめに

AIシステム部・AI研究開発グループの益子です。 現在はオートモーティブ事業において、AI研究開発エンジニアとして働いています。

先月20日、DeNA社内において、アマゾン ウェブ サービス ジャパン(AWS)様より「Amazon SageMaker」ハンズオンを実施していただきましたので、その模様をレポートさせていただきます。

DeNAでは、すでに数多くのサービスでAWSを活用しています。私の所属するAIシステム部もその例外ではなく、機械学習のモデル開発に幅広く利用しています。

昨年のAWS re:Invent 2017において「Amazon SageMaker」が発表されましたが、発表の後さっそく社内でも利用したいという声が上がり、AWS様より社内エンジニア向けハンズオンを実施していただけることになりました。

Amazon SageMakerとは

Amazon SageMakerとは

  • AWSインスタンス上にJupyter Notebookを構築
  • Notebook上での機械学習モデル実装
  • AWSのインフラを利用した、分散学習
  • 学習したモデルを組み込んだ予測APIの自動生成

まで一貫して行える、フルマネージドサービスです。 https://aws.amazon.com/jp/blogs/news/amazon-sagemaker/

Jupyter Notebookといえば、すでにデータ分析/機械学習アルゴリズム開発においてデファクトとなりつつあるツールですが、それがコンソールからポチポチするだけで、簡単に構築できるのはかなり大きなメリットとなります。

img1.png

SageMakerの機能 (講義資料より)

また、これまで機械学習サービスを開発する場合には

  1. 学習環境構築とデータ整備 (インフラエンジニア)
  2. 機械学習モデル実装(機械学習エンジニア)
  3. 学習済みモデルをサービス内にデプロイ(サービス開発エンジニア)

の手順が必要であり、案件によっては複数のエンジニアが関わる必要がありました。

SageMakerにより1.と3.の手順がほぼ自動化されるため、機械学習エンジニアはモデル実装に集中でき、また単独でサービス展開まで行うことも可能になります。

ハンズオンの流れ

20180309_190140.jpg

当日は、AWSより志村誠さんを講師に迎え、主に機械学習アルゴリズムのサービス適用という話題を中心に講演していただきました。

前半はスライドを用いてSageMakerの概要の説明、後半は実際に弊社環境内にJupyter Notebookを立ち上げて、ハンズオンという形式になっています。

ハンズオン参加者の内訳

DeNAからはエンジニアを中心に50名超参加しました。

chart_capture.png

参加者の内訳

参加者の内訳を見ると、幅広い分野のエンジニアが参加しています。また今回エンジニア向けとして開催したのですが、ビジネスメンバーからも参加があり、機械学習への関心が非常に高いことが伺えます。

それでは、以下当日のハンズオンの流れに沿って、詳細をレポートしていきます。

前半: 講義

前半は講義形式をとり、SageMakerについて解説していただきました。

img2.png

講義資料より

SageMakerを利用して機械学習を行う場合、主に3つの選択肢があります。

  • ① AWSが提供するアルゴリズムを利用
  • ② AWSがサポートするフレームワークを利用
  • ③ それ以外のアルゴリズム・フレームワークを利用

もっともお手軽なものが①で、すでにある程度の機械学習アルゴリズムはプリセットとして用意されています(後述)。

②は①に含まれないアルゴリズム、例えばディープラーニングモデルを独自に実装したい場合に利用することになります。対応しているフレームワークは限られていますが、分散学習もサポートされるので、柔軟性もありつつ、クラウドのメリットを享受できます。

もっとも柔軟性があるのは③の方法ですが、こちらは学習用のDockerコンテナを自前で用意する必要があり、一手間必要です。その代わり、①、②で提供されていないアルゴリズム・フレームワークが利用可能となります。 DeNAではchainerで開発しているチームも多く、その場合は③の方法になります。今後も①〜③の方法を適材適所で使い分けていくことになると思います。

①のAWS提供アルゴリズムですが、すでに一般的な回帰・分類問題などがカバーできるように用意されているようです。

img3.png

講義資料より

今回のハンズオンでも、①Amazon提供のアルゴリズムを利用した線形回帰問題のケースを実装していきました。

後半: ハンズオン

img4.png

当日の様子

ここからは、参加者全員分のJupyter Notebookインスタンスを立ち上げ、実際にSageMakerによる機械学習をいくつか試していきます。

Notebook インスタンスの作成

Notebookに利用するインスタンスタイプなどを設定するだけで、あっという間にJupyter Notebookが立ち上がりました。 notebook_creation.png img5.png

AWS提供アルゴリズムによる線形回帰 - 学習

サンプルとして、まずはAWS提供アルゴリズムの線形回帰モデルを試しました。 img6.png

img7.png

ハンズオンに使用したノートブック

データロードの部分は省きますが、AWS提供のアルゴリズムを利用した場合、上記コードだけでモデル学習を実行してくれます。学習用の関数であるlinear_estimator.fitを実行すると、Notebook インスタンスとは別に学習用のコンテナが立ち上がり、ジョブを実行してくれます。

img8.png

講義資料より

内部の挙動としては、SageMakerがS3から事前に配置した学習データを読み込み、コンテナ上で学習、学習した結果のモデルを再度S3に書き戻しておいてくれる、という仕組みになります。

S3に出力される学習済みモデルファイルですが、AWS提供アルゴリズムの場合はSageMaker専用になっているためエンドポイント経由での推論が前提となります。一方でDLフレームワークで独自実装した場合や、学習用コンテナを用意して学習したモデル(手法②、③)に関しては、S3から直接モデルファイルを取得して推論アプリケーションに組み込むことができるそうです。

AWS提供アルゴリズムによる線形回帰 - デプロイと推論

img8_2.png

講義資料より

学習が終われば、上記のようにdeployを実行するだけで推論エンドポイントが作成されます。

img9.png

講義資料より

作成したエンドポイントに対して、入力データを投げると、推論結果が返ってきます。ハンズオンではHTTPリクエストをする代わりに、ノートブック上から直接エンドポイントを実行する方法をとりました。 img10.png

今回割愛させていただきますが、ハンズオンではその他、tensorflowによるirisデータセットの分類問題にも取り組みました。

DeepAR による時系列予測

講演の中では、DeepAR 使った時系列予測タスクも紹介されましたので、手元でも試してみました。

データセットとして予め波形データを作成し、これを学習させます。 img11.png

データセット

ここでは実行コードは省きますが、全体の処理の流れは線形回帰で試したものと同様です。

img12.png

DeepARによる推論結果

推論結果として、80%信頼区間と予測中央値を得ることができました。 トレンドはうまく捉えられているようですが、ピーク部分にずれがあります。ここはさらなるチューニングで改善できるかもしれません。

DeepARは元々、Amazon.com内における予測タスクに利用していたものだそうです。 AWS提供アルゴリズムのため、特別なセットアップをする必要なく、時系列予測問題に適用することができます。 時系列予測モデルはビジネスシーンでも利用頻度が高く、例えば機械学習アルゴリズムには詳しくないエンジニアやアナリストが、とりあえず現場のデータで精度が出るかやってみたい、という場合に使えそうです。

まとめ

以上、ハンズオンでは実際にAWS上で機械学習アプリケーションの学習とデプロイまでを行うことができました。

モデルの実装から推論用のエンドポイントの作成まで、特別インフラを意識する必要はありません。機械学習エンジニアにとってはよりアルゴリズム開発に集中できるのではないかと思います。

現在Google Cloud Platform上にも同様なサービスとして「Cloud Machine Learning Engine」がありますが、機能の違いなど比較すると面白そうです。

最後に、個人的に便利だと思った点をいくつか上げておきます。

  • 単純にmanaged Jupyterとしても利用できる
    • SageMakerはモデル実装から学習、デプロイまで一貫して行えるサービスですが、それぞれ一部だけ利用することもでき、Jupyter Notebookだけの利用も可能です。これを使えば簡単にGPUインスタンス上にJupyterを立ち上げてさっと使う、ということもできそうです。
  • データの暗号化に対応
    • 学習データ/推論結果も、プロダクションレベルにおいては高いセキュリティレベルでの取扱いを要求される場合も多く、データを暗号化する仕組みがサポートされているのは助かります。

注意点も上げておきます。

  • 現在SageMakerは東京リージョンでは提供されていませんので、実際のサービスに組み込む際には留意しておく必要があるでしょう。
  • Notebookインスタンス数など、SageMaker に利用するリソースはアカウントごとに上限が設定されています。もし社内で大規模に利用する場合には、事前に上限を上げる申請をしておく必要があります。(今回のハンズオンでも実施しました。) https://docs.aws.amazon.com/jajp/general/latest/gr/awsservice_limits.html

以上.

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

DeNA TechCon 2018 開催レポート[4]

SWETグループの加瀬です。
DeNA TechCon 2018の開催レポートもいよいよ今回で最後となります。

過去のレポートはこちら
第1回 第2回 第3回

今回は、ORANGE Stage 『DeNAのゲーム開発』とClosingの発表の紹介です。

『逆転オセロニア』における運用効率化支援 〜デッキログのデータマイニング〜

tech_con_day4_1_resized.jpg

『逆転オセロニア』における運用効率化支援 〜デッキログのデータマイニング〜 from DeNA

AIシステム部 AI研究開発グループの田中による、『逆転オセロニア』でのデッキ分析手法の発表でした。

デッキ構築型のゲームアプリでは、各プレイヤーの使用デッキが固定化してしまうとゲームの楽しみが損なわれてしまいます。そのため、ゲーム内で現在よく使われているキャラやデッキの状況を把握することは、運用するにあたり非常に重要です。
発表では、実際の対戦ログからデッキに組み込まれるキャラの関係性や、キャラの特徴的な組み合わせを抽出して可視化することでゲーム運用に活用している事例が紹介されました。

大規模ゲーム開発におけるbuild高速化と安定化

tech_con_day4_2_resized.jpg

大規模ゲーム開発における build 高速化と安定化 from DeNA

ゲーム・エンターテインメント事業本部 Japanリージョンゲーム事業部の田辺による、アプリゲームのビルド改善の発表でした。

昨今のスマートフォンゲーム開発は大規模化・複雑化しており、ビルド時間が長くなるという問題があります。発表ではUnityのAssetBundleビルドの高速化、Jenkinsでの分散ビルド、Sakashoを用いるDeNAのゲーム開発特有の自動化フローなど、ビルドに関するノウハウが紹介されました。

協業アプリ開発を推進するテクニカルコンサルタントの挑戦 〜『歌マクロス』を成功に導く技術支援〜

協業アプリ開発を推進するテクニカルコンサルタントの挑戦 〜『歌マクロス』を成功に導く技術支援〜 from DeNA

ゲーム・エンターテインメント事業本部 Japanリージョンゲーム事業部 開発基盤部の高橋による、テクニカルコンサルタントに関する発表でした。

DeNAでは協業開発体制によって開発・運用されているゲームタイトルもあり、テックコンサルはそのようなタイトルの技術的な課題への対応を行っています。発表ではパフォーマンス対策といった技術的な内容から、運用のための体制の整備などといった多岐にわたるテックコンサルのサポート内容、過去に起きた問題の解決事例まで、非常に幅広い内容が紹介されました。

世界へ向けたゲーム開発 〜ローカライズ支援ツール『LION』〜

tech_con_day4_3_resized.jpg tech_con_day4_4_resized.jpg Japanリージョンゲーム事業部 開発基盤部の立浪と、グローバル推進部の中本による、内製のローカライズ支援ツールの発表でした。

世界へ向けたゲーム開発 〜ローカライズ支援ツール『LION』〜 from DeNA

ゲームのローカライズを行うには、翻訳対象となるファイルの用意からスケジュール調整など非常に複雑なタスクが数多く存在し、それらを手作業で行うことは困難となっています。
発表では、開発しているローカライズ支援ツール『LION』によってタスクの管理がどのように効率化されるかという内容が、実際のスクリーンショットも交えながら話されました。

DeNAのネイティブアプリにおけるサーバ開発の現在と未来

tech_con_day4_5_resized.jpg

DeNAのネイティブアプリにおけるサーバ開発の現在と未来 from DeNA

ゲーム・エンターテインメント事業本部 Japanリージョンゲーム事業部 開発基盤部の北澤による、ゲーム開発のサーバー側の発表でした。

DeNAの多くのゲームアプリでは、サーバー側の実装にSakashoと呼ばれる内製のBaaSを使用しており、ゲームによくあるサーバー側のロジックはSakashoに集約されているため、効率的に開発が行われています。
発表では「現在」として、Sakashoを開発した経緯やその結果の現在の状況が紹介されました。そして「未来」として、現状を振り返って判明してきた問題点を改善する次のプロダクトを開発中であるという内容が話されました。

Closing

tech_con_day4_6_resized.jpg DeNA TechCon最後の発表は、取締役の川崎よりClosingとしてまとめの話がありました。

DeNAでは近年AIやオートモーティブ事業に注力しており、それらが未来への仕込みから現実的にサービスを作る段階になったことで、今年は去年よりも発表される内容が具体的になってきました。
事業の幅が広くなったことにより色々な働き方ができるようになった反面、隣の部署がやっていることが見えづらくなってきているので、DeNA TechConによってDeNAの社員も隣の部署がどのような技術を使っているのか知る機会となり、価値が高いイベントになっています。
DeNAはビジネスが強い会社だと思われることが多いですが、ものづくりにも強くてビジネスと両輪になっている、という内容の話でした。
発表後、参加者に飲み物が配られ、乾杯と共にそのままAfter Partyが始まりました。

tech_con_day4_7_resized.jpg

最後となる第4回は、ORANGE StageとClosingの紹介でした。 2018年のDeNA TechConの開催レポートは今回で終了となります。
お越し頂いた皆様、登壇された皆様、スタッフの皆様、お疲れ様でした!!

最後に、レポートでは紹介できませんでしたが、当日は4つのStageに加えてCasual Talkの発表も並行して行われていました。
Tech Conのホームページではここまで紹介してきた発表と、Casual Talkのスライドと動画が公開されていますので、ぜひ訪れてみてください。

それでは、来年もDeNA TechConでお会いしましょう!

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

try! Swift Tokyo 2018 参加レポート

はじめに

17新卒iOSエンジニアの神武(@koooootaken)です。 2018/03/01-02に、ベルサール新宿グランドで、Swiftに関するコミュニティ主催のカンファレンス、 try! Swift Tokyo 2018に参加してきました。その様子をお伝えします。

tryswift

try! Swift Tokyo 2018の雰囲気

try! Swift Tokyo 2018では1つの会場で参加者全員が同じセッションを聞く形式で行われました。カンファレンスにしては珍しい。

会場

セッションは大半が英語で、トランシーバーによる同時通訳が行われていました。同時通訳は感動もので、喋りながら聴き、専門用語盛りだくさんの発表をよく精度高く通訳できるなと。発表者から聞いた話しによると、事前に日本語と英語の原稿を渡し通訳者さんと打合せしているそうです。日本語で発表されている方も、スライドに日本語はほとんどありませんでした。

参加者も海外の方が多く、隣の席の方が英語で声を掛けてくださった時には慌ててしまいましたが、そのまた隣の席の日本の方のお力も借り、どんな開発をしているかなどのコミュニケーションを取り盛り上がることができました。

また、Q&AブースにはAppleの社員の方が7名も待機しており、とても重要なカンファレンスである様子が伺えました。

ここで、参加した社員の知見や感想を記したレポートを5つ、発表セッションごとに掲載します。

Introducing Charles for iOS @avon

コマース&インキュベーション事業部という新規事業をガンガン開発するチームに所属している @kozyty がレポートします。

みなさん!Charles使ってますか?便利ですよね。 発表は、 @avon が日本語で挨拶して「5年間日本語を勉強したけど全く覚えてないから、ここからはGoogle先生にお願いするね(意訳)」と、場を笑わせつつはじまりました。

そんな雰囲気のままCharlesをFLASHの開発のデバックのために作った話をしたあと、Charles for iOSを開発する理由について教えてくれました。

「プロキシ設定が面倒だったり、設定をしていたのを忘れて通信できなくなったりする」など辛かった点を教えてくれました。だからこそ、iOS上で Charlesを実行したかった!だからコードネーム CHARLIE が始まったとのこと。Charles for iOSの発表と同時に会場は盛り上がりました。

まとめると Charles for iOS の便利な点は以下とのことでした。

  • No more proxy settings (プロキシ設定が不要)
  • No longer need a computer (コンピュータが不要)
  • Wi-Fi and Mobile data(モバイルネットワークも使える)
  • 格好いい(格好いい)

個人的には、「モバイルネットワークは熱いな!」と思いつつも。 それ以上に強力だと感じた点は、「iOSでできることは端末側で行い細かいデバックはPCで行う」という本来あるべき姿になることでオーバーヘッドが削減されることなのではないか...?と感じました。移動中にロギングしたり簡単なデバックもできるのは良さそうですよね。

執筆時点(3/4)ではまだAppStoreにありませんが、審査が無事通過して利用できることを祈っています!!とても楽しみですね!

リンク

game @giginet

コマース&インキュベーション事業部でライブ配信の新規事業を開発している @noppefoxwolf です。

try! Swift Tokyo 2018は多種多様なSwiftに関するセッションを聴くことが出来ました。 その中でも異色のセッションといえばfastlaneのメインコントリビュータでもある、@giginet氏のgameではないでしょうか?

このセッションでは「Xcodeは実はゲーム開発環境だったのです」という力強い言葉から、Xcodeのゲーム開発ツール群を紹介して始まりました。 特にXcodeに2D Map Editorがあったことを知らなかった自分はこの瞬間からセッションに釘付けになりました。

giginet氏のインディーゲーム開発の経験からSpriteKitを紹介する場面では、 Riko(try! Swiftのメインキャラクター)を爆破するデモゲームの実装を紹介し、SpriteKitの実装の簡単さをユニークに表現されました。 ここでSKSceneのライフサイクルやタッチイベントハンドラーがUIKitでの開発に非常に似ている事に気がついた方も多かったと思います。

中盤はGameplayKitのコンポーネントを紹介。 ゲーム開発に必要なアルゴリズムやデザインパターンを簡単に扱えるフレームワークは工夫次第では通常のネイティブアプリ開発でも使えるのでは無いかと思いました。

またSpriteKitに関するOSSでの取り組みではUnityでのUniRxに相当するRxSpriteKitを実装していることや、 Apple以外のプラットフォームでSpriteKitを動作させるプロジェクトが存在している事にも言及。

Appleのこれからのゲーム開発環境に対して冷静に分析しつつも、ゲーム開発者ならではのユニークな切り口で会場を沸かせました。

ARKitの登場でSprite/SceneKitの開発需要は一層増してきました。 これまでのネイティブ開発者が同じSwiftを使って開発できる環境として、これらの技術をキャッチアップしていく必要性は感じつつもなかなか触れられずにいる方も多いのでは無いかと思います。 そんな中で@giginet氏のセッションは開発者にSpriteKitの可能性や取り組みやすさを再認識させるものだったのではないでしょうか。

リンク

Swift エンジニアのための Kotlin 入門 @designatednerd

SWETグループでテストエンジニアをしている @tobi462 がレポートします。DeNA Testing Blogでテストに関する記事も公開しています。

この発表ではSwiftと比較しながらKotlinを紹介するという内容でした。私自身もKotlinを学習中だったので注目していた発表の1つでした。

まずはKotlinが登場した背景について語られました。

  • IntelliJ IDEAを開発しているJetBrainsが、既存のJVM言語に満足できなかったので開発した
  • Clojure、Groovyは機能として不足していた
  • Scalaは望む機能を備えていたがコンパイル速度が遅い

次にSwiftとKotlinが似ている点について語られました。

  • リテラル
  • ジェネリクス
  • ファーストクラスとしての関数
  • map / filter / reduce などのリスト操作関数(ただし微妙な差異はある)

続いてSwiftとKotlinがお互いに盗むべきだと考える機能について紹介がありました。

  • Kotlin
    • guard-let によるアンラップ・早期リターン
  • Swift
    • apply による連続したプロパティ設定(レシーバ付きラムダ)

apply については、私も以前似たようなQiita記事を書いたことがあったので、やはりSwiftにも欲しい機能だと改めて思いました。

残りはKotlin/NativeやKotlinの学び方などについて説明があり、最後には「try! Kotlin」とのことで上手な締め方だと思いました。

この発表でも触れられていましたが、Androidエンジニアとのコミュニケーションにもつながると思うので、この機会にKotlinを勉強してみるのも面白いのではないでしょうか。

レスポンダチェーンを知ろう @samuelgoodwin

社内で(多分)一番最初にSwift4移行しました。Swift大好きエンジニアの @malt03 です。 この発表では、@samuelgoodwinさんがレスポンダチェーンについて詳しく解説されていました。

私は入社以来iOSアプリを触っているにも関わらず、イベントがレスポンダチェーンによって受け渡されていることを理解していなかったので、とても興味深いセッションでした。

発表の最後にもありましたが、Appleのドキュメントを参照すると、正確な情報を得られます。

レスポンダチェーンとは、UIResponder.nextでつながっている片方向リスト[注釈]です。 iOSにおいてイベントは、イベント毎に定義されたファーストレスポンダからこのレスポンダチェーンに従って受け渡され、チェーンの中で、初めにそのイベントを処理できたレスポンダがイベントの処理を行います。 通常、チェーンの最後はAppDelegateになっています。

発表では、nextにカスタムオブジェクトを代入しておくことが出来るとありましたが、私の見る限りnextはreadonlyであり、代入は出来ませんでした。 nextのgetterをoverrideすることは出来ますが、全てのイベント処理に影響するバグの温床になるので、個人的にはオススメしません。

レスポンダチェーンを使う場面として便利そうだと思ったのは、レスポンダチェーンに自分でアクションを流す、という使い方です。 独自アクションも、Responderで定義済みのアクションも流せます。


// Cocoa
NSApplication.shared.sendAction(#selector(NSResponder.pageUp(_:)), to: nil, from: nil)
// UIKit
UIApplication.shared.sendAction(#selector(MyViewController.showNext), to: nil, from: nil, for: nil)

UIKitではResponderのアクションは使うことはほぼ無さそうですが、Cocoaでは便利な場面もありそうです。

ちなみに、調査した感じCocoaのレスポンダチェーンはきちんとAppDelegateまでnextResponderでつながっていませんでした。sendActionするときちんと動いているので、どうやって動いているのか謎めいています。その辺りは近いうちにQiitaにまとめようと思っています。

[注釈] 正確に言えば、同じnextを持つレスポンダは複数存在するので木構造ですが、木構造として扱ってはいないのでリストと書いています。

超解像+CoreML+Swiftを使ってアプリの画像データ転送量削減に挑戦する @kenmaz

社内からの登壇者について神武がレポートします。

マンガボックスiOSエンジニアの@kenmazが、学習済みのモデルをiOSで利用するための最新フレームワークCoreMLを用いて、荒い画像を綺麗な画像に変換する、超解像技術(SRCNN)にtry! した成果を発表しました。

登壇する@kenmazさん

序盤のデモではマンガボックスiOSアプリを起動し、アプリ内の漫画ビューワーでギザギザした低解像度画像を、目に見えて分かる高解像度画像に、僅か1秒足らずで変換する様子を披露し、会場を沸かせました。

続けて、実現にあたりどのような壁にぶつかり改善してきたかについて、画像や表で比較しつつ語られ、最後には、超解像技術は漫画だけではなく様々な種類の画像に適応できる可能性を示し、UIImageViewのextensionとして超解像技術を利用できるライブラリを本日、オープンソースとして公開しました!と発表。

公開されたSRCNNKitは翌日のgithubのトレンド入りするなど、5分という限られた時間の中で注目を集めていました。

リンク

企業ブース

DeNAはゴールドスポンサーをさせていただき、企業ブースを展示しました。

ブースではSwiftエンジニアなら気になる!あんな質問、こんな質問をボードに並べ、該当する項目にシールを貼っていただくアンケートを行いました。用意したボードが1日目でみっちり埋まってしまい、2日目には即興で質問を追加し別のボードを用意するなど、多くの方にお答えいただくことができました。ありがとうございました!

ボードにシール

このボードを眺めながら他の会社の方と会話を弾ませたり、結果を見にきました!とブースに何度も足を運んでいただいたりと、コミュニケーションのきっかけとなる様子が伺えました。

アンケートの最終結果はこちら! アンケート結果1 アンケート結果2

アンケートにお答えいただいた方には、懇親会で横浜DeNAベイスターズが手掛けたオリジナル醸造ビールに引き換えられるシールクーポンか、飲めない方や懇親会に参加できない方向けにDeNAオリジナルスクリーンクリーナーをお渡しました。海外の方々にも日本語で「ビール、美味しかったです!」と声を掛けていただけました。

ブース担当者の集合写真をパシャリ(全員写ってないですね笑) 集合写真

おわりに

大規模なカンファレンスということで、OSSとして公開しました!近日公開予定です!など、try! した成果を誰でも活用できるようにしたよ、という発表が多い印象でした。自分もtry! して、みんなもtry! してみてね!と言えるようになりたい、と強く思いました。

閲覧いただき、ありがとうございました!

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

DeNA TechCon 2018 開催レポート[3]

DeNA TechCon 2018 開催レポート[3]

こんにちは!SWETグループの加瀬です。
DeNA TechCon 2018の開催レポートも今回で第3回目となりました。

第1回 第2回

今回はグラフィックレコーディングの様子と、BLUE Stage 『DeNAを支える技術』の発表を紹介いたします。

グラフィックレコーディング

第1回目のDeNA TechConのときから名物となっているグラフィックレコーディングが今年も行われました!
技術的な内容が多くて難しい発表も、絵によって話の流れが可視化されることでとても分かりやすくなりますね。

tech_con_day3_1_resized.jpg tech_con_day3_2_resized.jpg tech_con_day3_3_resized.jpg tech_con_day3_4_resized.jpg tech_con_day3_6_resized.jpg

SWETの取り組むImage Based Testing

tech_con_day3_7_resized.jpg tech_con_day3_8_resized.jpg

SWETの取り組むImage Based Testing from DeNA

システム&デザイン本部 品質管理部 SWETグループの薦田と坂本による、画像ベースの自動テストの発表でした。

前半は、画像ベースでのデグレをテストする手法の解説と、テストの実装コストを減らすためにクローラーが自律的にサイト内を巡回してテストを行う手法が紹介されました。さらに、機械学習を活用してクローラーを自動的にフォームからログインさせる方法についての話もありました。
後半は、ゲームアプリのUIテストが難しい点をUIパーツの画像を用いて解決する手法と、こちらも機械学習を用いて画面判定のための画像登録を省力化する方法を検討中であることが紹介されました。

サービス開発におけるフロントエンド・ドメイン駆動設計の実践

tech_con_day3_9_resized.jpg

サービス開発における フロントエンド・ドメイン駆動設計の実践 from TakefumiYoshii

システム&デザイン本部 デザイン戦略部 デザインエンジニアリンググループの吉井による、フロントエンドにおけるドメイン駆動開発のアーキテクチャの紹介でした。

ヘルスケア事業のサービスである『KenCoM』のサイトにおける複雑な各種データの表示・編集を行うために、OOPをReact + Reduxの構成に加えたHexagonal Redux構成が紹介されました。React + Reduxで問題となりやすい部分をこの構成がどのようにして解決しているのか実践的な内容となっています。

DeNA Private Cloud の現在と未来

tech_con_day3_10_resized.jpg

DeNA Private Cloud の現在と未来 from DeNA

システム&デザイン本部 IT基盤部の廣瀬による、DeNAのPrivate Cloudについての発表でした。

DeNAのPrivate Cloudについての発表は第1回のDeNA TechConから発表されており、今年で3回目の発表となります。今年は、「これまで編」ではPrivate Cloudへの数々の改善について紹介し、「これから編」ではOpenStackとコンテナなどに関しての内容が話されました。

DeNAの大規模ライブ配信基盤を支える技術

tech_con_day3_11_resized.jpg

DeNAの大規模ライブ配信基盤を支える技術 from DeNA

システム&デザイン本部 IT基盤部 第一グループの漢による、DeNAのライブ配信サービスに使われる配信基盤の裏側についての発表でした。

ライブ配信サービスの配信・視聴サーバーの構成、サーバーのキャパシティ指数とそれを用いたオートスケーリングの仕組み、CDNの利用やマルチリージョン対応など、ライブ配信を安定して大規模に提供するための技術が紹介されました。
また、現在は調査検証中である低遅延配信や、次世代コーデックへの対応といった今後についての話もありました。

内製ツールを使ったチート診断・脆弱性診断

tech_con_day3_12_resized.jpg

内製ツールを使ったチート診断・脆弱性診断 from DeNA

システム&デザイン本部 セキュリティ部 セキュリティ技術グループの汐田による、DeNAの脆弱性診断についての発表でした。

DeNAでは、各サービスのセキュリティの脆弱性診断を内部で行っています。発表ではゲームアプリのチートを例にして脆弱性が悪用された場合にどのような被害が起きてしまうのか、そしてどのような観点でチートを防いでいくのか、ということについて紹介されました。
セキュリティ技術グループでは診断ツールも内製で作成しており、ツールの機能やそれを用いてバイナリプロトコルを解析するデモも行われました。

以上、第3回はBLUE Stageとグラフィックレコーディングの紹介でした!
いよいよ最終回となる次回の第4回目では、ORANGE Stage『DeNAのゲーム開発』とClosingを紹介する予定です。

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

DeNA TechCon 2018 開催レポート[2]

こんにちは!SWETグループの加瀬です。
前回に引き続き、DeNA Tech Con 2018の様子をお伝えしていきます。
第2回となる今回は展示ブースの様子と、RED Stage 『DeNAのチャレンジ』の発表の紹介です。

発表会場外の様子

当日は4つのメインステージの外でも、ノベルティの配布や展示ブースで賑わっていました。

tech_con_day2_1_resized.jpg tech_con_day2_3_resized.jpg tech_con_day2_4_resized.jpg tech_con_day2_2_resized.jpg

中でも特に目を引いたSHOWROOMのブースでは、VRデバイスのOculus RiftとOculus Touchを使ってバーチャルSHOWROOMERの体験ができました。

自分の体を動かすことでVRのアバターを操作できるだけではなく、SHOWROOMでお馴染みであるギフティングも再現されており、 なんとVR空間の空から振ってくるギフトのひとつひとつを掴んで動かしたり投げたりすることも可能でした。 VR空間とはいえギフトに触ることができることで、本当にプレゼントを頂いたのだなという実感をより強く感じられると思いました。

 tech_con_day2_5_resized.jpg

SHOWROOMブースを体験している筆者の様子。

『SHOWROOM』の大規模化に伴う技術課題のソリューション ~演者・視聴者の熱量を支える負荷対策、HTML5対応など~

tech_con_day2_6_resized.jpg

SHOWROOM株式会社の池滝による、SHOWROOMが今まで行ってきた負荷対策と、PC版のHTML5対応に関する話でした。

サーバー側のオートスケーリングや、非同期化できる処理を非同期化するといった対策から、大勢のユーザーが大量にコメントやギフティングを行う状況を再現するスクリプトを実行してクライアント端末のCPUとGPUを計測しつつチューニングを行う負荷対策の取り組みなどが紹介されました。 また、PC版サイトにおける従来のAdobe Flash Playerを使った実装からHTML5に移行する取り組みについての紹介もありました。

AWS IoT を用いた DeNA オートモーティブアーキテクチャ

tech_con_day2_7_resized.jpg

オートモーティブ事業部の放地による、車両情報を集約するアーキテクチャについての話でした。

オートモーティブ事業部では、車両情報を集約する基盤をAWS IoTで構築しています。今回の発表では、車両の登録と車両情報の送信・保存・伝搬のフローを実現するために、MQTTやAWS IoT RuleEngine、AWS IoT ThingShodow、AWS Lambdaなどを用いたアーキテクチャが紹介されました。また、サービス利用者向けアプリからこの基盤の車両情報を取得する仕組みに関する内容の紹介もありました。

ヘルスケアサービスを実現する最新技術 〜HealthKit・GCP + Goの活用〜

tech_con_day2_8_resized.jpg tech_con_day2_9_resized.jpg

ヘルスケアサービスを実現する最新技術 〜HealthKit・GCP + Goの活用〜 from DeNA

DeSCヘルスケア株式会社の深谷と伊藤による、ヘルスケアサービスを実現するクライアントとサーバーの仕組みについての紹介でした。

クライアント側では、歩数を例にiOSデバイスからどのようにして情報を取得するかということについて具体的な紹介がありました。サーバー側では、Go言語+DDDによるウェブアプリケーションをGAEに構築していることと、そのデプロイ方法、さらにデータをどのようにしてBigQueryにアップして分析できるようにするか、という内容が紹介されました。

AndAppにおけるGCP活用事例

tech_con_day2_10_resized.jpg

AndAppにおけるGCP活用事例 from DeNA

オープンプラットフォーム事業部の鈴木による、GCPをフル活用したAndAppのシステム全容の話でした。

AndAppでは、運用の負荷を抑えたり、新しいことに挑戦しようという試みから、DeNAでは一般的であったオンプレ上の独自システムではなくGCP上にシステムを構築するという選択がされました。発表では、GCPの様々な各サービスについての基本的な紹介とAndAppにおける利用方法、またそれらがどのように組み合わされて全体システムが構築されているかという内容が紹介されました。

以上、第2回は展示ブースとRED Stageの紹介でした!
次回の第3回では、BLUE Stage 『DeNAを支える技術』のセッションを紹介する予定です。

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

try! Swift Tokyo 2018への協賛・登壇のお知らせ

こんにちは。Shimonです。

明日3月1日から開催されるtry! Swift Tokyo 2018にて、DeNAはゴールドスポンサーを務めます。

カンファレンス2日目には、11時50分から弊社松前が超解像+CoreML+Swiftを使ってアプリの画像データ転送量削減に挑戦すると題したセッションをお送りします。

DeNAブースでは、ペットボトルのお水のご用意や、ちょっとしたアンケートにお答えいただくことで、先着で横浜DeNAベイスターズ 球団オリジナルビールのプレゼント* をします。また、ブースにはDeNAの様々なサービスからiOSエンジニアも参加します。SwiftやiOS開発に関わる話もできたら嬉しいです。

あわせて、カンファレンス翌日3月3日にはワークショップを、来週3月8日には非公式なファンイベントとなるAfter talks day1の会場提供、運営のサポートもさせていただきます。

try! Swiftのスポンサー、ブース出展は初めてになりますが、お越しの皆様と積極的に関わることができたらと考えています。カンファレンス当日、ワークショップ、After talksともに、皆様にお会いできるのを楽しみしています!

*ブースではクーポンのお渡しとなり、ビールは2日目のParty内で配布を予定しています

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

DeNA TechCon 2018 開催レポート[1]

こんにちは!SWETグループの加瀬です。
この時期の恒例行事となった今年のDeNA TechCon 2018が2018年2月7日に開催されました。今年は第3回目の開催となります。

tech_con_day1_1_resized.jpg

今回から全4回の予定でTechConの様子をお伝えしていきます。第1回はOpeningとKeynote、そしてYELLOW Stage『DeNAが切り拓くAI』の発表の紹介です。

オープニング

tech_con_day1_2_resized.jpg

オープニングでは木村よりDeNA TechConの概要についての説明がありました。
DeNAは色々な事業に参入しており、その中のエンジニアも色々な領域でチャレンジをしています。それを知ってもらう場がDeNA TechConであり、また少しでも技術の進歩の役に立てればという思いが語られました。

Keynote - エンジニアが引っ張るDeNAの"モノづくり"

tech_con_day1_3_resized.jpg

エンジニアが引っ張るDeNAの"モノづくり" from DeNA

今年のKeynoteは、代表取締役社長兼CEOである守安からDeNAにおける"モノづくり"の発表でした。

自身は元々エンジニア出身で、DeNA初期の頃の主力事業であったEコマースの『ビッダーズ』(現『Wowma!』)に夜勤でシステムの監視をする仕事から関わっていたという話から始まり、その後の『モバオク』、『Mobage』、そして現在、力を入れているオートモーティブ事業まで、DeNAのサービスにおいて発生した技術的な課題と、それらをどのように解決してきたかということが語られました。

その中で、分業体制で開発されていたために開発スピードを出すことができなかったビッターズの反省から、当時アルバイトだった川崎(現取締役)にモバオクの開発を一任し、1人で3ヶ月という短期間で完成させたエピソードが紹介されました。

最後に、サービスづくりをエンジニアが引っ張ることと、サービスの課題を高い技術力で解決することをDeNAの強みとして持ち続けたい、という話で発表を締めくくりました。

深層学習を用いたコンピュータビジョン技術とスマートショップの実現

tech_con_day1_4_resized.jpg tech_con_day1_5_resized.jpg

深層学習を用いたコンピュータビジョン技術とスマートショップの実現 from DeNA

AIシステム部の西野と李による、現在のコンピュータビジョン技術の紹介と、その中の姿勢推定技術を活用したスマートショッププロジェクトについての話でした。

スマートショッププロジェクトとは、Eコマースで行われている商品推薦のような、一人ひとりに合わせた接客をリアル店舗でも行えるようにしようという試みです。 そのためには入店したお客の状況を把握する必要があり、カメラ映像から同一人物であることを検出するために姿勢推定技術をどのように用いているかという内容でした。

車両運行管理システムのためのデータ整備と機械学習の活用

tech_con_day1_6_resized.jpg tech_con_day1_7_resized.jpg

車両運行管理システムのためのデータ整備と機械学習の活用 from 英爾 関谷

AIシステム部の関谷と森による、車両運行システムを支える技術と、深層学習を用いて車両停車が可能な位置を自動的に見つける仕組みについての話でした。

自動運転、配車予測、経路探索といった車両運行管理システムがどのような技術によって実現されているかという紹介です。また自動運転を活用した物流オペレーションを実現するために、自動車が停車可能な安全で交通の妨げにならない位置を深層学習を用いて画像からどのように推定するかという内容でした。

ゲーム体験を支える強化学習

tech_con_day1_8_resized.jpg tech_con_day1_9_resized.jpg

DeNA TechCon2018 ゲーム体験を支えるための強化学習 from Jun Okumura

AIシステム部の奥村と田中による、アプリゲームのバランス調整を強化学習・深層学習で行うという話でした。

最近のアプリゲームは、リリースされてから長期間に渡り継続的にバージョンアップを続ける流れになってきており、DeNAがリリースしている『逆転オセロニア』においては新しいキャラクターを追加しながら全体のバランスを調整することが難しくなりつつあるという問題が起きています。 そこで強化学習・深層学習を用いて人間らしいプレイを行うAIを作り、そのAIによるシミュレーションを行うことでバランス調整に活用させるという取り組みについての内容でした。

深層学習を用いたコンピュータビジョン技術と運転行動モニタリングへの応用

tech_con_day1_10_resized.jpg tech_con_day1_11_resized.jpg

深層学習を用いたコンピュータビジョン技術と運転行動モニタリングへの応用 from Yusuke Uchida

AIシステム部の内田と本多による、コンピュータビジョン技術を活用した交通事故を減らす取り組みについての話でした。

深層学習を用いたコンピュータビジョン技術の解説と、それらを用いて運転中のよそ見や車間距離不足といった不安全行動を減らすことで重大な交通事後を減らすという取り組みが紹介されました。 また、大規模な演算処理が必要な深層学習をエッジデバイスである車両で行うために、精度を保ったまま演算数を減らす深層学習の軽量化手法についても発表がありました。

研究開発と事業貢献を両立させるAI組織の作り方

tech_con_day1_12_resized.jpg

YELLOW Stageの最後は、AIシステム部の山田によるDeNAのAI組織についての話でした。

DeNAのAI組織体制、AI/機械学習を活用したサービスの紹介、研究開発と事業開発の関わり方、AI・分析の基盤技術、AI研究開発エンジニアとデータサイエンティストの役割、先端技術をキャッチアップするための精度や設備といった非常に多岐にわたる内容の紹介と、今後力を入れていくところについての発表でした。

次回の第2回ではRED Stage『DeNAのチャレンジ』の発表を紹介する予定です。

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

サブカルのためのword2vec

はじめに

AIシステム部AI研究開発グループ アルバイトの五十嵐です。(@bonprosoft, ポートフォリオ:http://vbcpp.net/about/ ) 現在、東北大学大学院の修士1年で、大学院では(自然言語ではなく)高速な文字列処理アルゴリズムに関する研究を行っています。

私は2017年9月上旬から3週間ほど、アルバイト兼インターンとしてハッカドールチーム内のNLPのタスクに取り組んでいました。 その後はアルバイトとして、期間中にできなかった追加実験と実際の製品への適用に取り組んでいます。

取り組んだタスク

突然ですが、みなさま、ハッカドールはインストールされていますか? ハッカドールは、主にサブカルチャーに関する記事に特化した、ニュースアプリケーションです。 アプリケーション内のユーザーのクリックや「ホシイ/イラナイ」などのアクションを通して、ハッカドールがユーザーの好みを自動的に学習し、様々なジャンルの記事があるなかから、1日3回のおすすめ記事を配信してくれます。

さて、ハッカドールの裏側ではユーザーへ記事を配信するために日々膨大なWeb記事をクロールして、どの記事がどのジャンル・要素のものであるのかなどを識別し、検索サービスと同じようにユーザーへ記事を配信しています。 Web記事を適切に解析するためには、毎クール増えるアニメのタイトルはもちろん、話題となっている単語にもいち早く対応しなければなりません。

そこでハッカドールチームでは、形態素解析のための辞書を毎日自動的に構築するジョブを用意しています。 これにより、大部分の解析処理はうまくいくようになりますが、まだいくつかの課題が残っています。 それは、シノニム辞書の構築 です。 ここで言う「シノニム辞書」とは、アニメの作品名をはじめとした何らかの名称と略称/愛称を関連付けるための辞書のことを指しています。 シノニム辞書は、ハッカドール内において記事のタグ付けや検索において利用されています。 有名な例としては、次のようなものがあります。

  • ご注文はうさぎですか? ⇔ ごちうさ
  • Re:ゼロから始める異世界生活 ⇔ リゼロ
  • この素晴らしい世界に祝福を! ⇔ このすば

略称/愛称自体の分かち書きは、前述のジョブによりうまく動作しますが、その略称/愛称が指している名称との紐づけは現状自動的に獲得できておらず、この紐づけは現在手動で行っています。 2017年10月現在、シノニム辞書に登録されたエントリ数は約5600件にも達し、日々増えていくシノニムを今後も管理し続けるのはとても大変な作業です。 そこで今回は「シノニム辞書を何とか自動で獲得できないか」というタスクに取り組みました。

なお、シノニム辞書の自動構築にあたって、ハッカドール内で利用できるデータセットとしては次のようなものがあげられます。

  • 日々のWeb記事のクロール結果
  • アニメ/サブカルに関するタグ/キーワード集合
  • 日々更新される形態素解析用辞書
  • アプリ内の検索キーワード
  • 現時点で登録されているシノニムペア

以降の章では、先行研究と提案手法、評価実験に関する詳細を説明していきますが、もし読むのが大変に感じる場合や先に成果物だけを見たい場合には、次のURLからスライドとデモサイトをご覧ください。

サブカルのためのWord2vec from DeNA

先行研究

最初の1週間は、今回のタスク設定と近い、同義語獲得/同義性判定関連の先行研究を調査しました。 その結果、大きく分けて先行研究で用いられていた手法は、次の3種類に分けられると考えました。

  • 単語表記を考慮した同義語判定
  • 周辺文脈を利用した同義語判定
  • 検索クエリなどの関係情報を利用した同義語判定

それぞれの手法において、特に印象に残った論文を、簡単にご紹介します。

単語表記を考慮した同義語判定

同義語がもともとの名称をベースに作られることを仮定すると、編集距離などの表記を考慮した手法を適用することを考えるのが自然です。 2008年に高橋らが提案した手法[a]では、同義語を以下の3種類から生成されるものと仮定して、これらを考慮した同義語判定のためのフローおよび素性の作成を行っています。

  • 定型文字列の追加: 接頭/接尾辞等の文字列を追加
  • 表記変換: 読みを保存して表記を変換
  • 省略: 文字順を保存して文字を削除

判定ルールのなかには、例えば音節数を考慮した正規化や、SVMを用いた省略関係にあるかどうかの判定ロジックが含まれており、2つの単語の単語表記について、様々な観点から距離を計算するための手法が組み込まれています。

周辺文脈を利用した同義語判定

「同じ文脈に出現する単語は類似した意味を持つ」という分布仮説(Harris, 1954)に基づいて、単語の意味を表すベクトルを求めるためのモデルとして、近年ではSkip-gramモデル(Mikolov+, 2013,[b])を用いた研究が活発に行われています。 ここではSkip-gramモデルの詳細の説明は割愛させていただきますが、原理を簡単に説明すると、ある単語を与えたときに、出力と周辺に出現する単語が一致する確率が高くなるように図1の$W_e$と$W$を学習することで、適当なイテレーションを回した後に得られる$W_e$が単語ベクトルとして利用できるという仕組みになっています。 なお以降の図では、Skip-gramモデルを図1右下のような、省略された図を用いて表現することにします。(図1右上と右下は等価なモデルを示しています。)

図1 Skip-gramモデル ▲図1 Skip-gramモデル

Skip-gramモデルを利用した同義語獲得のアプローチとしては様々な手法がありますが、特に新しい手法として、城光らによって提案された、文脈限定Skip-gram(城光+, 2017,[c])があります。 この手法では、特定の品詞のみ/左右特定の位置のみを考慮するような制約を加えて、異なる制約を持った複数のSkip-Gramモデルを学習したあと、2つの単語ペアを与えたときに、これらのSkip-gramが出力するコサイン類似度を素性として、同義語か否かの教師あり学習を行っています。 論文中では、実際に合計254種類のSkip-gramを学習させたあと、これらのモデルを用いて同義語判定を行ったところ、通常のSkip-gramモデルだけの場合と比較して、F値が大幅に向上したと述べています。

検索クエリなどの関係情報を利用した同義語判定

同義語判定は検索エンジンにおいても重要となります。 2012年にMicrosoft Researchから発表された論文では、固有表現のシノニムを自動的に検出する手法に用いる指標の一つとして、Pseudo Document Similarity(Kaushik+,2012,[d])が提案されました。 この指標の前身となったClick Similarity(Cheng+, 2010,[e])は、2つのクエリの類似度を測るための手法として、検索クエリ集合とWebドキュメント集合を頂点とした二部グラフを考えたうえで、ある検索クエリからあるWebドキュメントにたどりついたときにエッジを張り、2つのクエリが与えられたときに、その値がどの程度一致するかという情報を用いています。 これに加えて、Pseudo Document Similarityでは、特に検索クエリが複数の単語からなる場合にもRecallがあがるよう、エッジの張り方を工夫しています。

先行研究の本タスクへの適用

先ほど挙げたそれぞれの手法を、今回のタスクへ適用することを考えてみます。はじめに次の例をご覧ください。

  • 終末何してますか?忙しいですか?救ってもらっていいですか? ⇔ すかすか
  • 友達ない ⇔ はがない

この例は、近年放送されたアニメの作品名とそのシノニムのペアを示しています。 1番目の例は、すかが3回繰り返し出現しているにもかかわらず、シノニムはそのうちの2回から構成されています。 また、2番目の例では、有用と思われる名詞や形容詞、漢字表記などを無視して、シノニムは主に助詞から構成されています。

これは主観ですが、1クール毎に増えるアニメ作品名の略称の競合を避けるためにも、作品名からのシノニムの推測は年々難しくなっていると考えています。 したがって、単語表記を考慮した同義語判定は、今回のタスクへ適用するのは難しいと考えました。

続いて、周辺文脈を利用した同義語判定ですが、単語分割さえできていればSkip-gramの学習が可能であり、周辺単語から単語自体が出現するコンテキストを推測する(単語表記を考慮しない)という性質から、今回のタスクにおいて応用可能であると考えました。 しかし、城光らの手法では、2つの単語がシノニムの関係にあるかどうかを判定するために、シノニムペアを教師データとして使用しており、教師データ作成のコストが必要です。 さらに、分類機の入力として合計254種類ものSkip-gramを用いており、この手法でモデルを頻繁に更新するのは難しいと考えました。

最後に、検索クエリなどの関係情報を利用した同義語判定ですが、今回のタスクへ適用するにはエッジを張るために必要な情報が足りません。 これは、検索クエリなどはデータセットに含まれるものの、その後のユーザーの行動に関する情報が含まれていないため、先行研究のようなエッジを張ることができないためです。 代わりに、検索クエリが文章に含まれているという関係をエッジとして使うことを考えましたが、この関係が果たしてどれくらい有効に働くかという点が見通せなかったため(3週間という限られた時間のなかで成果を出すため)今回はこの手法の採用を見送りました。

以上の理由から、今回のタスクは周辺文脈を利用した同義語判定ベースの手法で取り組みました。 しかし城光らの手法をそのまま適用することは難しいため、予備実験として、ひとまず従来のSkip-gramを学習させたうえで、何か改善できる点がないかを調べました。

予備実験

従来のSkip-gramを用いて単語ベクトルの獲得を行い、シノニムを与えたときのk近傍を観察してみます。

実験設定

学習に用いたデータセットとしては、Webからクロールした記事250,000件を使用しました。 このデータセットに含まれる単語数は533,999単語(のべ123,273,881語)です。

Skip-gramの学習に関する主要なハイパーパラメータとしては、窓幅を5単語、学習する単語ベクトルの次元を100次元としました。 また、ある単語の出現回数が全データセット中で5回より少ない場合には、その単語を学習から除外しました。 したがって最終的には、172,257単語(のべ93,799,316語)の単語を用いて学習を行いました。

実験結果

次の表は、学習済みモデルを用いて、アニメ作品のシノニムの単語ベクトルとコサイン類似度の高いベクトルを持つ5単語をそれぞれ列挙したものです。

表1 従来のSkip-gramを用いたときの、シノニムの単語ベクトルとコサイン類似度の近いベクトルを持つ上位5単語
ごちうさ
(ご注文はうさぎですか?)
リゼロ
(Re:ゼロから始める異世界生活)
このすば
(この素晴らしい世界に祝福を!)
けもフレ
(けものフレンズ)
よう実
(ようこそ実力至上主義の教室へ)
#1 リゼロ 0.71542 ごちうさ 0.71542 幼女戦記 0.67590 二次創作 0.58515 プリアラ 0.71460
#2 きんモザ 0.70086 ガーリッシュナンバー 0.69933 はいふり 0.65225 エンドレスエイト 0.57156 クロムクロ 0.66699
#3 まどマギ 0.67969 緋弾のアリア AA 0.66972 ハルチカ 0.63882 シュタゲ 0.55419 ガーリッシュナンバー 0.63846
#4 ラブライブ 0.67866 ワンパンマン 0.66917 リゼロ 0.63733 グレンラガン 0.54987 えとたま 0.61215
#5 アイマス 0.67314 幼女戦記 0.66810 暗殺教室 0.63500 ラブライブ 0.54697 正解するカド 0.60950

それ以外の単語で試した場合でも、上の表と同様にして、アニメタイトルを表す単語を与えた場合には、何らかのアニメタイトルを表す単語がk近傍に存在するという結果になりました。

しかし「ごちうさ」から「ご注文はうさぎですか?」、「リゼロ」から「Re:ゼロから始める異世界生活」が捉えられないことから、同一の作品を表すアニメタイトルの距離が近くなるように学習できていないことが分かります。 言い換えると、従来のSkip-gramでは、アニメタイトル同士は正しく距離が近くなるように学習されるものの、それ以上の特徴は捉えられていないということが分かります。 (この結論は、一度でもword2vecを使ったことのある方なら、頷いていただけると思います。)

したがって、今回のタスクを解決するには、従来のSkip-gramでは難しいという結論になりました。

予備実験に関する考察

先ほどの表1をご覧ください。 従来手法では「ごちうさ」に類似したベクトルを持つ単語として「リゼロ」が、また「リゼロ」に類似したベクトルを持つ単語として「ごちうさ」がそれぞれ出現しています。 これは、学習の結果で得られた100次元のベクトル表現において「ごちうさ」と「リゼロ」がお互いに近い位置に存在するということを意味しています。 では、なぜ「ごちうさ」と「リゼロ」が近くなるのでしょうか。 以降ではこの問題を、ごちうさ-リゼロ状態として呼ぶことにしましょう。

ごちうさ-リゼロ状態はなぜ起こるのか

図2 「ごちうさ」(左)「リゼロ」(右)という単語の周辺5単語に出現する単語を、頻度の高い順にソートした結果
▲図2 「ごちうさ」(左)「リゼロ」(右)という単語の周辺5単語に出現する単語を、頻度の高い順にソートした結果

図2をご覧ください。 この表は、それぞれ「ごちうさ」「リゼロ」という単語の周辺5単語に出現する単語を、頻度を高い順にソートしたものです。

ところで、皆さんは、この表にあるような周辺単語の分布から「ごちうさ」「リゼロ」という作品名まで言い当てることができますか? (実際にアニメ作品名を知らせない状態で、作品の正式名称を除いた分布を与えて作品名を推測してもらったところ、あくまで主観ですが、半数程度の人が異なる作品名を答えていました。) 確かに作品を表すような特徴を持つような単語を含んでいるものの、基本的に確信を持って言えることは「アニメ作品」(もしくはサブカル全般)ということ程度かと思います。 Skip-gramを含むWord2vecは、基本的にこのようなタスクを解くことを目標にして、単語ベクトルを学習しているのです。

さて、図2をよく観察すると、次のことが言えます。

  1. 「店舗限定」や「コラボ」などの、今回のタスクにおいてはノイズとなりそうな単語が上位に来ている
  2. 「アニメ」「キャラ」「イベント」などのアニメ全般で使われる単語が上位に来ている

この2点を手掛かりに解決策を探していきます。

まず一つ考えられる要因としては、複数作品に関して言及している記事が学習に含まれているという点です。 図3は、クロールされた記事に、アニメ/サブカルに関するタグ/キーワード集合(タスク設定の章で説明)を用いて付与されたキーワードの数に関するヒストグラムです。

クロールされた記事に付与されたキーワードの数
▲図3 クロールされた記事に付与されたキーワードの数

キーワードを多く含むような記事としては、どのようなものがあるのでしょうか? 実際にデータセットを確認してみると、コミックマーケットをはじめとしたイベントにおける出展情報に関する記事が多く含まれていることがわかりました。 「リゼロ」や「ごちうさ」のような人気作品はグッズも多く取り上げられることから、出展情報に関する多数のウェブページに出現しており、これが、ごちうさ-リゼロ状態の一つの要因になっているのではないかと考えました。

また二つ目に考えられる要因として、単語ベクトルの学習に周辺単語を使うだけでは、今回のタスクを解くには不十分であるという点です。 周辺単語を見ると、アニメ全般で用いられるような単語が多く出現していることがわかります。 これらの単語はWord2vecの学習において、一般名詞のなかからアニメ全般に関する概念を獲得する(アニメに関する単語の距離が近くなるように学習する) には重要ですが、今回のような、もう少し詳細にアニメ作品を考慮した単語ベクトルを獲得したい場合には、これらの アニメ全般用語は、いわばストップワードと同じ扱いになると言っても良いでしょう。

次の章では、アニメ作品に関するドメインの知識を考慮するような仕組みを組み込んだモデルを提案します。

提案手法

前述の要因二つについて、まず一つ目の解決策としては、前処理として1記事にキーワードを10個以上含む記事については除外を行いました。 これにより、なるべく1つの作品について言及しているようなWeb記事からのみ学習を行うようにするという狙いがあります。

二つ目に解決策ですが、学習モデルにこのキーワード情報をうまく埋め込むことで、アニメ作品に関するドメインの知識も単語ベクトルに埋め込むことができないかを検討しました。 そこで考えたのが、以下の3つのモデルです。

モデル1号

モデル1号
▲図4 モデル1号

モデル1号は、ある単語を入力としたときに、その周辺単語とドキュメントに付与されたキーワードを出力として学習を行うモデルです。 つまり、通常のSkip-gramモデルに加えて、キーワード情報を推測するような層を途中に付け足して、マルチタスク学習を行っています。

モデル2号

モデル2号
▲図5 モデル2号

モデル2号は、ある単語と、その単語が出現するドキュメントに付与されたキーワード情報を入力としたときに、その単語の周辺単語を学習するモデルです。 これが学習できると、単語だけではなく、あるキーワードが出現するドキュメントにおいては、特定の単語が周辺に出現しやすいという、条件付きの周辺単語の推測もできるようになります。 また、単語ベクトルの学習と同時に、キーワード情報に関するベクトルも学習できる点も魅力的です。

モデル3号

※こちらのモデルは、インターン期間終了後に追加実験として試したモデルです。

Rev. A

モデル3号 Rev.A
▲図6 モデル3号 Rev.A

モデル3号 Rev.Aは、基本的にはモデル2号と同じです。 しかし、モデル2号では1つのドキュメントに複数のキーワードが付与されていた場合に、そのSumを取って入力としていたところを、このモデルでは1つずつ入力として取るようにした点が異なります。 このように変更することで、モデル2号と比較して全体のモデル構成が浅くなり、学習が進みやすいのではないかと考えたためです。

Rev. B

モデル3号 Rev.B
▲図7 モデル3号 Rev.B

モデル3号 Rev.Bは、Rev.Aに加えて、concatの後に1層のFully Connected層を挟んでいます。 これにより、例えば入力として与えられたキーワード情報が周辺単語の推測に役に立たないような場合でも、学習が可能になるのではないかと考えました。

Rev. C

model3c.pngのサムネール画像
▲図8 モデル3号 Rev.C

モデル3号 Rev.Cは、Rev.Bに加えて、ResNet(He+, 2016,[f])で用いられているようなShortcut Connectionを加えました。 これにより、仮にキーワード情報を用いた場合のほうが性能が悪くなるような場合でも、最悪時の性能を通常のSkip-gramと同等くらいに保証できるのではないかと考えました。

キーワードのみSkip-gram

図9 キーワードのみSkip-gram
▲図9 キーワードのみSkip-gram

これは、モデル1号において、周辺単語への出力層を無くしたものと一致します。 すなわち、マルチタスク学習の有効性を検証するために実験に用いたモデルです。

キーワードのみSkip-gramは、基本的にモデル構成はSkip-gramと同様ですが、ある単語を入力としたときに周辺単語を学習するのではなく、ある単語が出現するドキュメントのキーワード情報を学習している点が異なります。

評価実験

従来のSkip-gram、キーワードのみモデル、モデル1号~3号 Rev.Cまでをすべて実装し、評価実験を行いました。 なお、すべてのモデルはChainerを用いて実装しました。

実装は後日公開予定です。

評価手法

現在ハッカドールが持っているシノニムペア5600組を用いてモデルの評価を行うために、次の3つの評価手法を用いました。

  • コサイン類似度
  • K近傍一致度
  • 相互ランク

コサイン類似度

コサイン類似度は、単純にシノニムペアがどれくらい近くなっているかを測定するための指標として取り入れました。

シノニムペアを$x, y$としたときに、コサイン類似度$cos(x,y)$は次のように定義されます。

$$\text{cos}(x,y) = \frac{\sum_{i=0}^d{w_{x_{i}} w_{y_{i}}}}{\sqrt{\sum_{i=0}^d{w_{x_{i}}^2}} \sqrt{\sum_{i=0}^d{w_{y_{i}}^2}}}$$

ここで、$w_{x}$は単語$x$の単語ベクトル、$d$は単語ベクトルの次元を示しています。

k近傍一致度

k近傍一致度は、シノニムペアとなる2単語の周辺に存在する単語がどれくらい一致しているかを測定することを目的として取り入れました。

シノニムペアを$x, y$としたときに、単語$x$(単語$y$)に対するコサイン類似度が高い上位$k$単語を集めた集合を$S_{x}$($S_{y}$)とします。 すなわち、すべての単語集合を$S$としたときに、$S_{x}$($S_{y}$)は次の2式を満たすように定義されます。

$$|S_{x}| = k$$ $$ \forall p \in S \setminus S_{x}.~\forall q \in S_{x}.~\text{cos}(x, p) \le \text{cos}(x, q)$$

このとき、k近傍一致度$\text{Jaccard}_{k}(S_{x}, S_{y})$は次のように定義されます。

$$\text{Jaccard}_{k}(S_{x}, S_{y}) = \frac{\sum_{w \in S_{x} \cup S_{y}}{\text{min}(\text{cos}(x, w), \text{cos}(y, w))}}{\sum_{w \in S_{x} \cup S_{y}}{\text{max}(\text{cos}(x, w), \text{cos}(y, w))}}$$

つまり、単語$x$と$y$のk近傍が、どれくらい一致しているかを重み付きのJaccard係数を用いて計算しています。

相互ランク

相互ランクは、単語$x$と単語$y$がどれくらい相互に近くなっているかを測定するための指標として導入しました。

単語$x$について、すべての単語とコサイン類似度を計算し、値の高い順にソートしたリストにおいて単語$y$が出現する順位を$d_{x\rightarrow y}$とします。 また単語$y$について、すべての単語とコサイン類似度を計算し、値の高い順にソートしたリストにおいて単語$x$が出現する順位を$d_{y\rightarrow x}$とします。

このとき、相互ランク$\text{rank}(x, y)$は次のように定義されます。

$$\text{rank}(x, y) = \frac{d_{x\rightarrow y} + d_{y\rightarrow x}}{2}$$

つまり、この値は単語$x$の類似単語を検索したときの単語$y$の順位と、単語$y$の類似単語を検索したときの単語$x$の順位の平均を示しており、この値が小さければ小さいほど良いモデルであると判断できます。

実験設定

学習に用いたデータセットとしては、Webからクロールした記事集合のなかで、1記事にキーワードを10個以上含まない記事集合から100,000件を使用しました。 このデータセットに含まれる単語数は331,138単語(のべ49,187,387語)、キーワード数は47,751です。

Skip-gramの学習に関する主要なハイパーパラメータとしては、窓幅を5単語、学習する単語ベクトルの次元を100次元としました。 また、ある単語の出現回数が全データセット中で5回より少ない場合には、その単語を学習から除外しました。 したがって、最終的には、114,045単語(のべ37,128,122語)の単語を用いて学習を行いました。

同様にして、頻度が5回以下のキーワードについても除外しました。 除外した結果、キーワードを含まなくなった記事については、特殊なキーワード(None)を与えました。 したがって、最終的には、キーワード数は11,824となりました。

また、k近傍一致度で用いた$k$の値は20としました。 スコアには、シノニムペア5600組に対してそれぞれの評価手法を適用したときの値の平均を採用しました。 ただし考察で述べる理由から、相互ランクにおいてのみ、中央値の算出も行いました。

実験結果

表2 モデルの評価結果
モデル コサイン類似度 K近傍一致度 相互ランク(平均値) 相互ランク(中央値)
従来のSkip-gram 0.4041 0.0660 9523.5263 892.0
キーワードのみモデル 0.5063 0.1918 5745.6675 22.5
1号 0.5293 0.1923 4926.6754 19.0
2号 0.3706 0.0532 14301.6743 2599.0
3号 Rev.A 0.3348 0.0544 12626.5088 1696.0
3号 Rev.B 0.3599 0.0616 11804.2098 1296.5
3号 Rev.C 0.3585 0.0619 12003.0603 1292.0

実験結果から、従来のSkip-gramと比較すると、提案したモデル1号の性能は大幅に向上していることがわかります。 では実際に、どのような出力がでるようになったかを実際に試してみましょう。

表3 モデル1号を用いたときの、シノニムの単語ベクトルとコサイン類似度の近いベクトルを持つ上位5単語
ごちうさ
(ご注文はうさぎですか?)
リゼロ
(Re:ゼロから始める異世界生活)
このすば
(この素晴らしい世界に祝福を!)
けもフレ
(けものフレンズ)
よう実
(ようこそ実力至上主義の教室へ)
#1 ご注文はうさぎですか? 0.87631 Re:ゼロから始める異世界生活 0.78200 めぐみん 0.84121 たつき監督 0.73934 ようこそ実力至上主義の教室へ 0.70415
#2 ご注文はうさぎですか?? 0.85684 長月達平 0.67824 ダクネス 0.79038 けものフレンズ 0.73272 zitsu 0.57993
#3 チノ 0.82150 エミリア 0.67667 この素晴らしい世界に祝福を! 0.77038 サーバルちゃん 0.72079 軽井沢 0.56846
#4 シャロ 0.75929 レム 0.67260 駄女神 0.75584 アライさん 0.69193 清隆 0.55031
#5 千夜 0.74842 MJ文庫J 0.64899 カズマ 0.74682 ドッタンバッタン 0.66814 綾小路 0.54770

表1と比較すると、既存手法に比べて、取りたかったものがだいぶ取れていることが分かります。ほかの例も試してみましょう。

図10 従来手法(Skip-gram)と提案手法(モデル1号)の比較
▲図10 従来手法(Skip-gram)と提案手法(モデル1号)の比較

図10の例では、様々な単語を既存手法と提案手法(モデル1号)に与えたときの類似5単語を示しています。 この例から、例えば「すかすか」→「週末なにしてますか?忙しいですか?救ってもらっていいですか?」といった既存手法では獲得するのが難しいと思われていたシノニムも正しく獲得できていることがわかります。 また「ほたるん」(のんのんびよりのキャラクターの愛称)を与えた場合に、既存手法ではキャラクターの語尾や一般名詞などが混在し、正しく距離を計算できていない結果となってしまっていますが、提案手法では 同作品のキャラクターの愛称が近くなるようなベクトルが得られていることにも注目です。 さらに「お仕事シリーズ」や「マスター」といった単語を与えた場合にも、ユーザーが想定しているであろう作品関連の単語が近くなるように学習されており、従来手法と比較すると、提案手法ではアニメタイトルやキャラクター同士が近くなるのはもちろん、作品なども考慮して距離が計算されるように制約がかかっているように見えます。

考察

相互ランクの値が大きいシノニムペアの特徴

はじめに、モデル1号について、実際にモデルに単語を与えたときの印象と比べて、評価データでの相互ランクの平均値が大きい(順位が低い)ことに注目しました。 そこで、モデル1号の相互ランクのヒストグラムを求めた結果、次の図のようになりました。

図11 モデル1号の相互ランクに関するヒストグラム
▲図11 モデル1号の相互ランクに関するヒストグラム

図11から、一部の相互ランクの値が大きいシノニムペアに影響されて、平均値も大きくなっていることが推測できます。 これが、実験において相互ランクの中央値を求めた理由です。

では、モデル1号ではどのようなシノニムペアが相互ランクの値が大きくなっているのか(すなわち、正しく取れなかったのか)を考察してみます。 評価データとして用いたシノニムペア 5600組のうち、モデル1号で相互ランクの値が大きかった(順位が低かった)シノニムペアを観察した結果、大きく分けて次の5種類に分類されると考えました。

  • 表記ゆれによる単語の重複
  • 評価データセットに古いデータが含まれている
  • 評価データセットに一般名詞が含まれている
  • 評価データセットにセリフ・その他が含まれている
  • 同じ単語で複数の意味を持つ単語が存在

1番目の項目は、例えば「ニコ生」と「にこなま」のような単語です。 Web記事において出現する単語の数は、前者のほうが圧倒的に多く、後者が出現することはまれです。 つまり、前者は正しく学習することができますが、後者は正しく学習することが難しくなります。 このため、評価データに含まれる「にこなま」などの表記ゆれがある単語とのシノニムペアは、距離が離れてしまうと考えました。

2番目の項目は、例えば(「ワールドイズマイン」,「ワイズマ」)のようなシノニムペアが評価データに含まれているケースです。 今回の学習に用いたデータセットは、2014年3月~2017年9月の期間に公開された記事で構成されており、その期間より古いものや新しいもので出現するような単語については、正しく学習することが難しいという理由が考えられます。

3番目の項目は、例えば(「コメント」,「comment」)のようなシノニムペアが評価データに含まれているケースです。 今回の学習には、主にサブカル関係のWeb記事をデータセットとして用いており、マルチタスク学習にもアニメ作品関連のキーワードを利用しています。 そのため、一般名詞に関する順位は低いままでもおかしくないと考えました。

4番目の項目は、例えば(「イチロー」,「打ってみた」)のようなシノニムペアが評価データに含まれているケースです。 これらは主にニコニコ動画などのサービスで、動画のタグ機能として用いられているのをよく見かけますが、2番目の理由と同様にして今回の学習で獲得するのは難しいと考えました。

5番目の項目は、例えば「私モテ」や「とある」のような単語です。 例えば、前者の「私モテ」は「私がモテないのはどう考えてもお前らが悪い!」(2013年7月アニメ化)と「私がモテてどうすんだ」(2016年10月アニメ化)の2作品の愛称として知られています。 実際にGoogleで検索した場合にも、両方の作品が表示されていることがわかります。 後者の「とある」は、アニメ分野においては「とある魔術の禁書目録」「とある科学の超電磁砲」の2作品を指し、さらに一般的には連体詞として用いられています。

このような場合には、複数のコンテキストで同一の単語が出現することになり、正しく学習することが困難になります。 実は、このような曖昧性解消問題はアニメ関連においても深刻な問題となりつつあり、上記の作品名以外にも、例えば「凛」という名前が指すキャラクターが多い(有名なところでは「星空凛」「松岡凛」「遠坂凛」「渋谷凛」など)という問題があります。 このアニメドメインにおける曖昧性解消問題を凛状態と呼ぶことにしましょう。

凛状態の解決に向けて

では凛状態を解決するにはどうすれば良いでしょうか。

「どの凛を指しているかはキーワードと周辺文脈から区別できる」という仮定を置くと、次のナイーブなアルゴリズムを考えることができます。

  1. キーワードごとに異なる「凛」となるように区別
  2. 提案モデルを学習
  3. 1エポックごとに「凛」間の距離を測り、一定閾値以下であればマージ
  4. 2.へ戻る

図12 凛状態解決に向けたアルゴリズム
▲図12 凛状態解決に向けたアルゴリズム

3週間のうちに実際に実験することはできませんでしたが、上記のアルゴリズムを組み込むことで、適切にコンテキストの異なる同一単語を分離することができるのではないかと考えています。

モデル2号・3号の単語ベクトルのスコアが低い理由

従来のモデルとモデル2号・3号は、出力として周辺単語を予測するように学習を行っており、スコアの高いキーワードのみモデルとモデル1号は、出力としてキーワード情報を予測するように学習を行っています。 このことからも、評価実験でのスコアに大きく貢献したのは、キーワード情報からのロスであると考えることができます。

ところで、モデル2号と3号もキーワード情報をモデルの入力として用いています。 この入力は、本当に無意味だったのでしょうか?

評価実験では単語ベクトル$W_e$のみを評価していたためスコアとしては現れていませんが、実はキーワードベクトル$W_e$にも面白い特徴が得られていました。 モデル3号 Rev.Bの学習を通して得られた$W_d$に表1,3と類似したキーワードを与えると次の結果が得られました。

表4 モデル3号 Rev.Bを用いたときの、キーワードの単語ベクトルとコサイン類似度の近いベクトルを持つ上位5キーワード
ご注文はうさぎですか? Re:ゼロから始める異世界生活 この素晴らしい世界に祝福を! けものフレンズ ようこそ実力至上主義の教室へ
#1 ココア 0.68947 レム 0.78615 めぐみん 0.83319 サーバル 0.82906 よう実 0.69769
#2 シャロ 0.67518 エミリア 0.69870 ダクネス 0.73124 サーバルちゃん 0.77726 セントールの悩み 0.55141
#3 ティッピー 0.56429 長月達平 0.66962 駄女神 0.61180 ジャパリパーク 0.72899 恋と嘘 0.54268
#4 きんいろモザイク 0.51485 スバル 0.3048 ダークホース 0.60308 けもフレ 0.72134 紗霧 0.53223
#5 のんのんびより 0.51027 鬱展開 0.56276 角川スニーカー文庫 0.56557 かばんちゃん 0.71177 夏アニメ 0.48676

これもこれで面白い結果が出ていますね。 例えば「ご注文はうさぎですか?」に類似したキーワードとして「きんいろモザイク」や「のんのんびより」が出現している点や、「Re:ゼロから始める異世界生活」に「鬱展開」というキーワードが出現している点、さらには「ようこそ実力至上主義の教室へ」に類似したキーワードとして同時期に放送されたアニメなどが多数含まれている点など、何らかの知識が埋め込まれていると考えて良さそうです。

この結果から、モデル2号や3号においてモデルの学習に役立つアニメドメインに関する知識はキーワード情報からの入力を直接受け取る$W_d$が獲得しやすいため、$W_e$ではドメインに特化しない一般的な単語ベクトルの獲得が行われた、すなわち$W_e$にアニメドメインに関する知識の埋め込みが行われなかったのではないかと考えることができます。

これを踏まえると「なぜ1号のようにマルチタスク学習を行わなかったのか?」と疑問に思われる方も多いと思います。 実は今回の記事を執筆するにあたって間に合わなかったという理由もあるため、この実験は今後のタスクの1つでもありますが、実験を通して以下の2つの問題も出てくるのではないかと考えています。

  • 入力と出力に同じデータが来るため、正しく学習されない可能性もある
  • (他のモデルと比較して)学習時間が大幅に増加する
    • 入力と出力のキーワード情報の組み合わせが二乗個になるため

モデルファイルとデモサイト

今回の取り組みで得られた単語ベクトルがどのようなものかを、実際に試せるデモサイトを次のURLで公開しました。

このウェブサイトでは、上部に単語を入力しEnterキーを押すことで、各モデルにおける類似度が高い単語(入力された単語のベクトルとコサイン類似度が高いベクトルを持つ単語)を検索することができます。 利用できるモデルは次の通りです。

  • Original Raw (250k, 100dim) : 従来のSkip-gram(250,000件のWeb記事を元に学習)
  • Original (100k, 100dim) : 従来のSkip-gram (100,000件の前処理済みWeb記事を元に学習)
  • Keyword Only (100k, 100dim) : キーワードのみモデル (100,000件の前処理済みWeb記事を元に学習)
  • Model 1 (100k, 100dim/Best) : モデル1号(100,000件の前処理済みWeb記事を元に学習。提案モデルのなかで最も精度が高い。)
  • Model 1 Large (1M, 300dim/Best) : モデル1号(1,000,000件の前処理済みWeb記事を元に学習。提案モデルのなかで最も精度が高い。)
  • Model 2 (100k, 100dim) : モデル2号 (100,000件の前処理済みWeb記事を元に学習)
  • Model 3 Rev.A (100k, 100dim) : モデル3号 Rev.A (モデル2号と同様)
  • Model 3 Rev.B (100k, 100dim) : モデル3号 Rev.B (モデル2号と同様)
  • Model 3 Rev.C (100k, 100dim) : モデル3号 Rev.C (モデル2号と同様)

また、学習済みの単語ベクトルも配布しますので、手元に環境がある方はこちらでも試してみてください。

なお、配布形式には次の3種類あります。

  • tsv : 単語にスペースを含めることを許容するために、独自のフォーマットとなっています。単語と値の間がタブ区切りになっています。値はスペース区切りとなっています。
  • Google-txt : Googleが公開したword2vec実装の出力形式(テキスト形式)に準拠しています。 そのため、既存のword2vec実装で読み込むことができます。(単語と値の間がスペース区切りとなっています。そのため単語にスペースが含まれる場合(1つのエントリが複数語からなる場合)には、アンダーバー_ で置換されています。)
  • Google-bin : Googleが公開したword2vec実装の出力形式(バイナリ形式)に準拠しています。 Google-txtと同様の処理が行われています。

まとめ

今回の3週間のインターンでは、アニメやサブカルに関連したシノニムの自動獲得タスクに取り組みました。 1週間目では、同義語獲得に関する先行研究の調査を行い、主な既存手法の要点を整理しました。 2週間目では、予備実験として、Skip-gramモデルを用いて現状のデータセットから単語ベクトルを学習し、得られた単語ベクトルから現状のタスクに適用する場合の問題点(ごちうさ-リゼロ状態)を調査しました。 また、予備実験で明らかになった問題点から、改善するための仕組みを取り入れたモデルを提案・実装し、評価実験を行いました。 評価実験の結果、提案モデルはアニメ作品に関する知識も同時に埋め込んだ単語ベクトルを獲得できることが明らかになり、従来のモデルよりも高い精度で今回のタスクを解くことが可能となりました。 3週間目では、これらの実験モデルに関する考察とデモの作成を行いました。 考察を通して、特に複数のコンテキストを持つ同一単語の単語ベクトルを学習することが困難である(凛状態)ことがわかり、アニメドメインにおける曖昧性解消の必要性について言及しました。

今回の提案手法によって得られた単語ベクトルの応用先の例として、ハッカドール内における検索システムで用いる同義語辞書などが挙げられます。 その理由として、例えばユーザーが「ごちうさ グッズ」のようなクエリで検索した場合に「(ごちうさ OR ご注文はうさぎですか? OR チノ OR ココア OR ...) AND (グッズ OR トートバッグ OR ...)」のように展開されたクエリで検索を行うほうが嬉しい場合もあるからです。

また、今回はキーワード情報としてアニメ関連の単語を使用しましたが、異なるドメインと関連した単語をキーワード情報として用いることで、別のドメインに関する知識を単語ベクトルに埋め込むことができると考えています。 例えば、料理やお店に関する情報をキーワードとして持っておき、これらの単語を文章のキーワード情報として与えることで、幅広い分野に本提案モデルを適用できるでしょう。

今後のタスクとしては、凛状態の解決とモデル2号・3号の性能改善などが挙げられます。

最後に、インターン開始前から業務内容をはじめ様々な点でお世話になりました、メンターの鴨志田さん、人事の戸上さん、山本さんに感謝いたします。 土田さん、濱田さんには特に研究を進めるうえで有益なアドバイスをいただきました。ありがとうございます。 本タスクに関して一緒にディスカッションしてくださった鈴木政隆さん、内田さんにも感謝いたします。

そして、今回のインターンを無事に終えるにあたって、さまざまな場所で支えてくださった、AIシステム部とハッカドールチームの皆様に、心から感謝いたします。

参考文献

[a] 高橋いづみ, et al. "単語正規化による固有表現の同義性判定." 言語処理学会第 14 回年次大会発表論文集 (2008): 821-824.http://www.anlp.jp/proceedings/annual_meeting/2008/pdf_dir/D4-5.pdf
[b] Mikolov, Tomas, et al. "Distributed representations of words and phrases and their compositionality." Advances in neural information processing systems. 2013. http://papers.nips.cc/paper/5021-distributed-representations-of-words-and-phrases-and-their-compositionality
[c] 城光英彰, 松田源立, and 山口和紀. "文脈限定 Skip-gram による同義語獲得." 自然言語処理 24.2 (2017): 187-204. https://www.jstage.jst.go.jp/article/jnlp/24/2/24_187/_article/-char/ja/
[d] Chakrabarti, Kaushik, et al. "A framework for robust discovery of entity synonyms." Proceedings of the 18th ACM SIGKDD international conference on Knowledge discovery and data mining. ACM, 2012. https://www.microsoft.com/en-us/research/wp-content/uploads/2012/01/idg811-cheng.pdf
[e] Cheng, Tao, Hady W. Lauw, and Stelios Paparizos. "Fuzzy matching of web queries to structured data." Data Engineering (ICDE), 2010 IEEE 26th International Conference on. IEEE, 2010.
[f] He, Kaiming, et al. "Deep residual learning for image recognition." Proceedings of the IEEE conference on computer vision and pattern recognition. 2016. https://www.cv-foundation.org/openaccess/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る

chainercvを用いたMask R-CNNの実装

はじめに

皆さんこんにちは。DeNAのAI研究開発エンジニアの本多です。DeNAからは初日のRealtime Multi-Person Pose Estimationにつづき2回目のChainer Advent Calendar への投稿となります。私は2017年よりDeNA AIシステム部にジョインし、以来コンピュータビジョンの研究開発に従事しております。 12/16に行われた第43会CV勉強会@関東にてICCV 2017現地レポートをさせていただいたこともあり、同学会でBest Paper Awardを獲得した'Mask R-CNN' [1]を、chainercvをベースに実装してみることにしました。

rcnn_1.png

図1 実装したMask R-CNNによる推論結果

背景

Mask R-CNNは、一つのネットワーク・モデルで、以下のような複数の情報を取得することのできるマルチタスク検出器です。

  • 画像中の物体位置と大きさ (bounding box)
  • 物体のカテゴリ (人なのか、ソファなのか)
  • 物体のセグメンテーション (画素レベルでの物体位置)
  • 人の体パーツ位置 (頭・肩・足など)

一枚の画像の各ピクセルをクラス分類するsemantic segmentationと異なり、本手法でのセグメンテーションは、オブジェクト毎の個別segmentationであることから、instance segmentationと呼ばれます。 例えば図1ですと、左の人と右の人は別のオブジェクトとしてsegmentationされています。ポーズ推定でも同様で、複数の人が別のオブジェクトとして認識されつつ、それぞれの体パーツの推定がおこなわれます。

このように、Mask-RCNNでは、画像内の物体領域を求め、それぞれの物体について個別に、詳細な情報を推論していくことができます。 今回は、chainercvのexampleに含まれており、Mask R-CNNの前身であるFaster R-CNNをベースに、簡単な変更だけでMask R-CNNの機能を実装していきます。

ネットワークの構成

Mask R-CNNのネットワークは、Extractorと呼ばれる特徴抽出器と、物体の候補領域をピックアップするRegion Proposal Network、そして各タスクに対応するheadと呼ばれる子ネットワークから構成されます。

①class and box head
②mask head

①はFaster R-CNNに含まれており、ピックアップした候補領域を1次元ベクトルに変換したのち、全結合ネットワークによりクラス分類、及び物体の境界であるbounding boxの位置を出力します。今回追加するのは②、すなわちセグメンテーションマスクを推定するためのheadネットワークのみです。

rcnn_2.png

図2 Mask R-CNNのネットワーク構成 [1] (K. He et al., 2017)

データセットの読み込み

学習にはCOCO dataset 2017のtrainを用います。 COCO datasetは、80のオブジェクト分類及び位置、セグメンテーションマスク、人に関しては体パーツ位置など、多くのアノテーションが付与されたデータセットで、13万枚程度の学習用画像が含まれます。データセットをサンプルする関数であるget_exampleが返すのは、画像と、bounding boxラベル、そして上記 セグメンテーションマスク の4つとなります。

ここでは、セグメンテーションマスクの読み込みについて説明します。 マスク情報は、ポリゴン座標のリストという形でアノテーションデータに含まれています。ある画像に対するセグメンテーション情報をseg_polygonsに読み込んだのち、

mask_in = np.zeros((int(h), int(w)), dtype=np.uint8)
for annot_seg_polygon in annot_seg_polygons:
       N = len(annot_seg_polygon)
       rr, cc =    polygon(np.array(annot_seg_polygon[1:N:2]),
                   np.array(annot_seg_polygon[0:N:2]))
       mask_in[np.clip(rr,0,h-1), np.clip(cc,0,w-1)] = 1

のようにして、ポリゴンをセグメンテーションマスクに変換しながらmask_inに格納していきます。ここで、マスクはバイナリで、'1'が物体のある場所を表します。ここでh,wは画像のサイズと同じです。

モデルの実装

実装は、chainercvのexamplesに含まれているfaster_rcnnをベースに行っていきます。

1.ExtractorとRegion Proposal Network

まず入力画像からfeature map (特徴マップ)を抽出します。

features = self.mask_rcnn.extractor(imgs)

ここでextractor(抽出器)は、mask_rcnnクラス内で

extractor = VGG16(initialW=vgg_initialW)

のように定義されています。今回はchainercvのFaster-RCNNに倣い、VGG16の5回目のmax poolingの直前までをextractorとして使用します。他にResNet等を使用することもできます。抽出されたfeature mapのサイズは元画像の1/16になります。

次にRegion Proposal Networkを適用し、物体の存在する領域(Region of Interest, ROI)を抽出します。chainercvのregion_proposal_network.pyを変更なく用いています。

2.教師マスクデータ

次に抽出されたROIに対し、ground truth (教師データ)を設定します。 chainercvのproposal_target_creator.pyでは、抽出されたROIそれぞれとオーバーラップの大きいground truthオブジェクトを見つけ、gt_assignmentというインデックスで関連づけています。これを利用して、マスクデータの読み込みを追加します。

gt_roi_mask=[]
for i , idx in enumerate(gt_assignment[pos_index]):
    A=mask[idx, np.max((int(sample_roi[i,0]),0)):np.min((int(sample_roi[i,2]),h)),        
          np.max((int(sample_roi[i,1]),0)):np.min((int(sample_roi[i,3]),w))]
    gt_roi_mask.append(cv2.resize(A, (masksize,masksize)))

ground truthマスクは、図3のように、positiveとなったROIに相当する領域sample_roiで切り出されます。ここでROIの大きさはそれぞれ異なるのですが、正解データは全て(masksize,masksize)に固定します。masksizeは例えば14です。

rcnn_3.png

図3 ground truthマスクの切り出し

ROIの切り出し方法については、本論文では新しく導入されたROI alignという手法により精度良く切り出しを行っています。本稿では簡単のため、Faster R-CNNで用いられており、chainerにも実装されているROI poolingを用います。ROI alignとROI poolingの違いについては、[2]をご参照ください。

3.Headネットワーク

ROI poolingで切り出されたfeature mapのサイズは、128(候補数) x 512 (channel数) x 7 x 7 (ROI大きさ)となっています。これを、各head networkに入力していきます。

ネットワーク定義は

  • class and box head (Faster R-CNNと同じ)
#Faster-RCNN branch
self.fc6 = L.Linear(512*roi_size*roi_size, 4096, initialW=vgg_initialW)
self.fc7 = L.Linear(4096, 4096, initialW=vgg_initialW)
self.cls_loc = L.Linear(4096, n_class * 4, initialW=vgg_initialW)
self.score = L.Linear(4096, n_class, initialW=score_initialW)
  • mask head (今回追加。サイズは7 x 7 から 14 x 14 に拡大される)
#Mask-RCNN branch
self.convm1_1 = L.Convolution2D(512,512,3,1,pad=1, initialW=None)
self.convm1_2 = L.Convolution2D(512,512,3,1,pad=1, initialW=None)
self.deconvm1 = L.Deconvolution2D(512, 256, 2, 2, initialW=None)
self.convm2_1 = L.Convolution2D(256, 256, 3, 1, pad=1,initialW=None)
self.convm2_2 = L.Convolution2D(256, n_class, 3, 1, pad=1,initialW=None)

ネットワークのforward実行は

  • class and box head
      fc6 = F.relu(self.fc6(pool)) 
      fc7 = F.relu(self.fc7(fc6))
      roi_cls_locs = self.cls_loc(fc7) 
      roi_scores = self.score(fc7)
  • mask head
       h = F.relu(self.convm1_1(pool))
       h = F.relu(self.convm1_2(h))
       h = F.relu(self.deconvm1(h)) 
       h = F.relu(self.convm2_1(h))
       masks=self.convm2_2(h)

のように行います。

4.損失関数

mask headのLoss(損失)計算のため、mask headの出力であるroi_cls_mask : 128(候補数) x 81(クラス) x 14 x 14 (マスク大きさ)から、対象ROIに存在する正解ラベルに該当するroi_mask :128(候補数) x 14 x 14(マスク大きさ) を抽出します。

roi_mask = roi_cls_mask[self.xp.arange(n_sample), gt_roi_label]

そして、同じく候補領域のground truth maskであるgt_roi_maskと比較し、損失を求めます。

mask_loss = F.sigmoid_cross_entropy(roi_mask[0:gt_roi_mask.shape[0]], gt_roi_mask)

ここでground truthは0 or 1 のバイナリで、ネットワーク出力は正負の値を持つfloat値です。損失関数としては、sigmoid cross entropyを用います。 これでmask lossが定義できました。Faster R-CNNのlossに、mask_lossを加えてできあがりです。論文で記載されているloss式に倣い、各lossの重み付けは行っていません。

loss = rpn_loc_loss + rpn_cls_loss + roi_loc_loss + roi_cls_loss + mask_loss

学習

さて、いよいよ学習です。COCO datasetは大きいので、epochでなくiterationで管理します。図4のように、およそ40万iteration (それでも3 epoch!)程度でlossの値が安定します。train lossの内訳を見ると、各lossの絶対値は異なりますが、mask loss (roi_mask_loss)も比較的初期段階から下降していきます。 セグメンテーションマスクの学習は、前述のように、候補領域に存在するオブジェクトの正解ラベルと正解マスクを用いて行われます。したがって、正確にラベル予想ができるようになる前(roi_cls_lossが下がる前)でもセグメンテーションの学習が進んでいると考えられます。

rcnn_4.png

図4 train lossの推移

推論

推論の実装では、学習に用いたネットワークの出力に若干の「後処理」を加えています。 Non Maximum Supression (NMS)、およびセグメンテーションマスクの表示です。 NMS処理は、推定したBounding Boxのうち、信頼度の高いものだけを残して、それらにオーバーラップするものを排除する処理で、chainercvのNMS実装をそのまま用いています。

セグメンテーションマスクは、我々の実装では、簡単に

for my in range(mask_size):
    for mx in range(mask_size):
        mxy = (bb[1]+width/14*mx, bb[0]+height/14*my)
        Mcolor=np.clip((M[my,mx])*1,0,0.5)
        ax.add_patch(plot.Rectangle(mxy, int(width/14)+1,int(height/14)+1,
        fill=True, linewidth=0,facecolor=COLOR[i%len(COLOR)], alpha=Mcolor))

のように、Bounding Box('bb')内を(mask_size(=14), mask_size)に分割して、maskネットワークの出力'M'に応じて四角形をアルファブレンドしていきます。簡易な表示方法ですが、人物のセグメンテーションが個別に行えていることがわかります。色はパレットを作り、オブジェクト毎にランダムに選定しています。

rcnn_5.png

図5 セグメンテーションマスク推論結果の可視化

まとめ

今回はICCV'17 Best PaperであるMask R-CNNの機能を、chainercvに追加するかたちで再現してみました。 実装はこちらにて公開しています。ぜひお試しください!

参考文献

[1]K. He, G. Gkioxari, P. Dollar, and R. Girshick. Mask R-CNN. In ICCV, 2017.
[2]yu4u, 最新の物体検出手法Mask R-CNNのRoI AlignとFast(er) R-CNNのRoI Poolingの違いを正しく理解する. https://qiita.com/yu4u/items/5cbe9db166a5d72f9eb8

ツイート
シェア
あとで読む
ブックマーク
送る
メールで送る