Cookpad Tech Kitchen #10を開催しました。

f:id:tsukasio:20170915160252p:plain

こんにちは、サービス開発部デザイナーの平塚です。

2017年9月13日(水)に、クックパッドオフィスにてデザイナー向けイベント「Cookpad Tech Kitchen #10」を行いました。

f:id:tsukasio:20170915160042j:plain

今回は「自社サービスで取り組むデザイン」をお題に、開発現場での実践事例を交えながら各社の文化やデザイナーの働き方についてご紹介しました。

お集まりいただいた皆さまの熱量も高く、イベントスタート時からQAセッション、懇親会に至るまで、とても充実した時間を過ごさせていただきました。 ご来場いただいた皆さま、本当にありがとうございました。

また今回は多数応募をいただいたため残念ながら抽選に漏れてしまった皆さま、たいへん申し訳ありません。 こういったイベントは今後も開催していきたいと思いますので、またのご参加を心よりお待ちしております!

一部ですが、イベントで行った各プレゼンテーションの概要をご紹介します。

「"料理の追体験"を実現するデザイン」

  • 若月 啓聡(Cookpad/デザイナー)

新機能タイムラインのデザインや、チームのユーザーとの関わり方についてお話を聞くことができました。

f:id:tsukasio:20170915160058j:plain

「はてなブログの世界観になじむ機能デザイン」

  • 松井 沙織(はてな/デザイナー)

はてなブログの新機能やUI変更の中で、書くことを邪魔しないデザインについてお話を聞くことができました。

f:id:tsukasio:20170915160114j:plain

「温度のあるサービスづくり」

  • 木坂 名央(GMOペパボ/デザイナー)

minneの、作家に向き合った温かみのあるデザインについてお話を聞くことができました。

f:id:tsukasio:20170915160133j:plain

「自然さを追求した音楽体験のためのUX」

  • 冨樫 晃己(CyberAgent/デザイナー)

AWAの、現実世界にありえる自然な動きについてお話を聞くことができました。

f:id:tsukasio:20170915160153j:plain

QAセッション

パネルディスカッションでは、

「UIデザイナーとUXデザイナーは兼任していますか? 実際の所UIとUXの兼任は難しいと思うのですがどのように分業や兼業していますか?」

「ドッグフーディングをチーム内で浸透させるのにはどうしていますか?」

といった参加者からの質問について、各社の取り組みについてより深く触れていただきました。

f:id:tsukasio:20170915164720j:plain

これからも楽しいイベントを企画していきます。 今後ともよろしくお願いします!


【クックパッドではデザイナー/エンジニアを積極採用中です】
ユーザー体験に向き合ってサービス開発をしたいデザイナーやエンジニアの方は、下記をご覧ください。

クックパッド採用情報 | UX/UIデザイナー
https://info.cookpad.com/careers/jobs/careers/ux-ui-designer
クックパッド採用情報 | エンジニア
https://info.cookpad.com/careers/jobs/careers/type/engineer

料理きろくにおける料理/非料理判別モデルの詳細

研究開発部の菊田(@yohei_kikuta)です。機械学習を活用した新規サービスの研究開発(主として画像分析系)に取り組んでいます。 最近読んだ論文で面白かったものを3つ挙げろと言われたら以下を挙げます。

クックパッドのアプリには「料理きろく」という機能があります。 携帯端末から料理画像のみを抽出して表示することで自分が食べたものを振り返れるようになっており、ここからレシピ投稿やつくれぽを送ることもできるようになっています。

料理きろくはユーザ数が約12万8千人、累積の写真判別枚数が約7900万枚、そのうち料理と判別された画像が約960万枚(数字は20170912時点)と多くの方々に使っていただいている機能です。 本記事では、その料理きろくのコアの技術部分である、機械学習による料理/非料理判別の詳細に関してお伝えします。 料理きろく全体のアーキテクチャに関してはここでは述べませんが、ご興味のある方は AWS Summit Tokyo での発表資料 をご覧ください。

料理きろくの背景と機械学習の役割

我々は、新しい技術を駆使してユーザ体験をより良いものに改善することで、クックパッドの使用頻度を増やしてもらったり、ユーザからもっとレシピやつくれぽを投稿してもらう、などの目標を持っています。 料理きろくはその目標に資する一つの施策であり、これは携帯端末に大量の食事情報が記録されていることから、それを活用してクックパッドのサービスに連携することを狙いとしています。 過去の自分の食事を振り返ることで食への楽しみや関心を高めてもらい、そこからレシピやつくれぽ投稿につなげたいというのが最初のターゲットとなっています。

ちなみに料理きろくではユーザのプライベートな画像を判別することになるため、全てサーバ上で処理がなされ、我々はユーザの画像を一切閲覧できないようになっています。

料理きろくにおける機械学習の役割は、料理/非料理を判別する高性能のモデルを提供することです。 機械学習によって正確に画像の料理/非料理が判別できるかどうかがサービス全体の質に直結するため、ここに Convolutional Neural Network (CNN) を用いたモデルを適用しました。 一口に CNN と言っても実に多様なので、データも拡充しながら、様々なモデルを試行錯誤をして改善を図りました。

以降では本番環境にデプロイしたモデルを中心に、どのような試行錯誤で改善をしていったのかをご紹介します。

最初にデプロイしたモデル

  • モデル:CaffeNet
  • データ:{料理,非料理}の二値ラベルの画像データ
  • フレームワーク:Chainer

最初のリリースでは CaffeNet というモデルを使っています。 これは ILSVRC2012 で優勝した AlexNet を少し変更したもので、pooling が Local Response Normalization の前に来ています。

最初の段階では、素早くリリースまで持っていきたい、社内に画像分析の知見がまだ蓄積していなかった*1、などの理由で、事例も多いこのモデルを採用しました。 データはシンプルに料理画像と非料理画像をとりあえず手当たり次第に集めたものを使用しました。 テストデータも集めた画像の一部をテスト用に切り出して、料理判別の精度と再現率をチェックするというごくごく基本的な手法でした。

本番運用に際しては、精度が低いと料理ではないものが表出されてユーザ体験が悪くなるという考えのもと、再現率をある程度犠牲にしても精度を高めるという方向で閾値を調整しました。 単純な二値判別では softmax の出力が0.5を超えれば料理と判別されることになりますが、このモデルでは閾値を0.9で設定しました。 これは閾値を変えながらテストデータでの結果を目視でチェックしながら定めたものです。

最初のモデルは手探りの部分も多かったですが、素早くリリースまで到達できたことは非常に良かった点で、継続的改善を遂行していける土台が整えることができたので後の改善につながりました。

一回目のモデルアップデート

  • モデル:Inception-v3
  • データ:{料理,非料理,複数の間違えやすい非料理カテゴリ}の多値ラベルの画像データ
  • フレームワーク:TensorFlow

最初にデプロイしたモデルでも結構精度が高かったのですが、自分たちでも使っていくうちに間違いやすい画像があることが分かってきました。 具体的には植物や赤ちゃんの画像などが間違いやすい傾向があることが判明したため、これらの画像にもロバストなモデルを作りたいという要望が出てきました。 また、CNN のモデルも様々な発展があるため、それらを検証してより基本的な性能が高いモデルを採用したいという考えもありました。

そこで、まずは様々な CNN のモデルを比較検証をして良いモデルを探すという実験をしました。 この頃には画像分析ができる人員も増えていたため、手分けをして実験をして GHE の wiki に情報を集約し、最終的に我々のデータセットに対して最も良い結果を出した Inception-v3 を採用することにしました。 モデルとして試したのは、{Inception-v3, GoogLeNet, ResNet, VGG, GAN を使った classification, NIN(軽量なモデルにも興味がある), …}、です。

フレームワークに関しても、TensorFlow を使う人が多くなったため、Chainer から切り替えました。 モデルの学習には Keras with TensorFlow backend を使っていますが、本番にデプロイする時は TensorFlow のみで動かすようにしています。 料理きろくのアーキテクチャはモデル部分を疎結合にしてあるので、この変更はそれほど大きなコストもなく実現できました。

次に単純な二値判別では問題として単純化しすぎているのではという考えのもと、多値判別に切り替えるという実験をしてみました。 思考回路としては、仮に世の中の料理画像の全集合が手に入ればその補集合が非料理画像だがそれは不可能→モデルは我々が集めた(非)料理画像の集合から(非)料理らしさを学習→これらは多様なので一つのカテゴリに集約し切るのは無理がありそう→特に間違いやすいものに関しては陽にカテゴリを作ってそちらに誘導したほうが我々が望むモデルができそう、という感じです。 料理/非料理ともに画像(二値ではなく多値のラベルを付与したもの)を追加収集して、それぞれが単一カテゴリ(この場合は多値の情報を潰して二値として扱う)の場合と複数カテゴリの場合とで性能を比較しました。 モデルの出力は一般に多値になりますが、判別結果としては多値の情報を潰して料理/非料理の二値判別として扱うようにしています。 全体的な性能を上げつつ特に精度を高めるものとして、料理は単一カテゴリとして非料理は多値カテゴリ(具体的には植物や人物を含む5カテゴリ)として扱うことに決定しました。

これらの改善によって、手元のデータで試験したところ、精度も再現率も向上し、特に間違えやすかった植物の画像に対しては間違いが約 1/3 に、赤ちゃんの画像に対しては間違いが約 1/20 ほどになりました。

これの取り組みは以前クックパッドで開催された Cookpad Tech Kitchen でも発表しています(発表資料)。

また、2017年度 人工知能学会全国大会 やIJCAIのワークショップとして開催された 9th Workshop on Multimediafor Cooking and Eating Activities などの学術的な場でも発表をしています。

二回目のモデルアップデート

  • モデル:Inception-v3 + patched classification
  • データ:{料理,非料理}の二値ラベルの画像データ、それらを14×14のパッチにしたもの
  • フレームワーク:TensorFlow

一回目のアップデートで大きく改善はしましたが、画像中に人と料理が同時に写っている場合はモデルが判断に迷う(人と判断すべきか、料理と判断すべきか)という問題が残っていました。 我々は「画像中の一部を切り取ってクックパッドのレシピとして掲載できそうなものは料理と判断する」という基準で料理/非料理を判断しているので、十分に料理が写っているのにモデルが非料理と判断されているものは改善の余地がありました。

この問題に取り組むために、まずはマルチラベルの判別をすることを考え、そのために Keras の ImageDataGenerator 辺りを改修したりもしましたが、データ準備のコストが高いため一旦保留としました。 次に、問題の根本は複数のものが写っているのにそれらをまとめて判別してしまっていることだと考え、画像をパッチに分割してパッチ毎に料理/非料理を判別するというモデルを構築しました。 具体的には、通常の Inception-v3 の出力付近で使う GlobalAveragePooling と Dense を、Conv2D や Dropout などを組み合わせて出力が 14×14×1 にするように置き換えて、sigmoid の出力で binary cross entropy を計算するようにしています。 パッチに分けることで料理と非料理を区別しやすくなることが分かったため、再び二値分類のモデル(ただしパッチ毎)になっています。 パッチサイズの 14×14 に関してはいくつかのパターンを実験した結果最も良い結果を返すものを選択しました。

このモデルの学習にはパッチ毎にラベルが付与されたデータが必要ですが、これは単純に元データをパッチに分割して、全パッチに元データと同じラベルを付与するという作り方でデータ準備を簡略化しました。 ただしこの作り方だと特に画像の端の部分が悪さをする可能性があるので、適切なラベルが得られるように一部の画像を crop したりもしています。

また、本番にデプロイした場合の性能を見積もるために、本番でのデータ分布に近くなるように社員から許諾を得て携帯端末のデータを提供してもらいました。 プライベートな画像のため、閲覧権限を絞って、特定の人が正解ラベルを付与してそれを使ってモデルの詳細な性能検証を実施しました。

このような改善を経て本番環境にデプロイされたモデルの結果の一例が以下の図となります。 色がついている領域が料理らしさが高い領域で、閾値以上のパッチを取り出してその領域が一定以上であれば料理と判別するというモデルになっています。

この改善によって、テストデータに対して精度を落とさずに再現率を5%以上改善することができました。 料理きろくは1000万というオーダーで画像を処理しているので、改善のインパクトは大きなものとなります。

モデル構築に使用したデータ

クックパッドには大量の料理画像があるので正例のデータには事欠きませんが、モデルの学習には負例のデータも重要になるため Creative Commons のデータや社員からデータを集めたりして様々な画像を収集しました。 プロジェクトの進行と共に画像を追加して試行錯誤してという作業を繰り返し、結果としてトータルで数十万枚程度の画像を扱いました。

どのような画像が重要になったかは上述のモデルアップデートでもご紹介しましたが、改めてモデルの性能向上に重要であった特徴的なデータをいくつか挙げたいと思います。

  • 料理 
    当然ながら正例としての料理画像は最重要のデータとなります。 クックパッドの豊富な料理画像データを用いて充実したデータセットを構築することができました。
  • 人(特に赤ちゃん) 
    人物画像は判別を間違えた場合のリスクも高い(ユーザ体験の観点から)ため、負例の中でも特に気をつけて画像を収集して学習に用いました。
  • 植物 
    想像に難くないですが、色合いや形状から誤判別される場合が多かったのが植物の画像でした。
  • 植木鉢 
    植物と似ていますが、植木鉢の場合は器もあるためにより一層誤判別されるものが多かったです。 そのため意識して負例としてデータを収集しました。
  • 料理が乗っていない空の皿
    料理には皿がつきものなので、皿があれば正例と勘違いしかねないため何も乗っていない皿も負例としてデータに追加しています。
  • 本番運用時にモデルが扱うデータ分布に近いテストデータ
    本番ではユーザの携帯端末中の画像が対象ですが、学習は収集したラベル付きの限定的なデータを用いているので、モデルの正しい性能が測りづらいという問題があります。 ユーザの画像は我々も閲覧できないため、この問題はオフライン/オンラインに限らず原理的な問題です。 そこで、許諾を得た社員のスマホのデータを使い、人力でラベルを付け、これを使ってモデルの評価を実施しました。 プライベートな画像であるため、閲覧権限を必要最低限の人間に絞って詳細な性能評価をして、他の人には統計情報のみを共有するという手法を採りました。

やはり学習データは最重要ですね。 料理きろくにおいては、多くの人の協力によって様々なデータを収集することができたので、非常に心強かったです。

今後の展望

料理きろくのプロジェクトを通じて、やはり継続的な試行錯誤に基づいた適切な改善策を講じることが重要であることが再認識できました。 それゆえに、これで完成ではなく、日進月歩の Deep Learning 技術を取り込んだり、データを拡充したりして、よりユーザにとって有用なモデルを構築し続けるのが大事だと考えています。

例えば最新の SENet や料理ドメインに特化した 横方向に広くスライスした畳み込み を試してみたり、自分たちで使いながら判別を間違った画像を収集してその傾向を探る、より高速に動作するモデルを構築するなど、改善の方向性は様々です。

「自分ならもっと良いモデルが作れる!」という人がいましたら是非一緒にやりましょう。

おまけ

以前 Twitter で話題になっていた画像として、犬と食べ物の区別が難しい画像というものがありました。 みなさんは下の画像のどれが犬でどれが食べ物かが判別できるでしょうか? 遠目で見ると判別はかなり難しい感じがします。

画像は以下から引用させていただきました。
左の画像:https://twitter.com/teenybiscuit/status/707727863571582978
右の画像:https://twitter.com/ohmycorgi/status/867745923719364609

これらの画像に我々の料理/非料理判別モデルを適用して、料理画像だけを抽出してもらうとしましょう。

見事に料理画像だけを選び出すことができました! Deep Learningのモデルが適切に料理とそれ以外を区別できていることを伺い知ることができます。

これ以外にも、近い内容の話として 弁護士の柿沼太一先生との対談 などもあります。 ご興味があれば是非ご覧ください。

まとめ

クックパッドアプリの料理きろくという機能で用いている料理画像判別技術に関してお伝えしました。 CNN のモデル自体はもの凄く特殊なものを構築しているわけではありませんが、試行錯誤を経たモデルの変遷やその過程で遭遇したタスク特有の問題点などに興味を持っていただけたなら幸いです。 本記事でお伝えしたのは一例であり、クックパッドでは様々なサービスにおいて、発展著しい機械学習の技術をユーザに有益なものへと昇華させる取り組みに日々励んでいます。

いかがでしたでしょうか。 クックパッドでは、機械学習を用いて新たなサービスを創り出していける方を募集しています。 興味のある方はぜひ話を聞きに遊びに来て下さい。 クックパッド株式会社 研究開発部 採用情報

*1:このプロジェクトが始まった段階では私はまだ入社していませんでした

データ分析からUI改善

こんにちは。サービス開発部デザイナーの平塚です。

クックパッドでは一部のデザイナーは日々の業務でSQLを書いて数値を見たり、リリースした施策の分析を行っています。 このエントリーでは機能をリリースしてデータ分析し、そこからUI改善を行った事例について紹介したいと思います。

なぜデザイナーがデータ分析?

サービスやプロダクトを改善するには現状について定性的・定量的の両方を理解しておく必要があります。
そのため、自分が進める施策やデザインするものを数値で把握しておくことで、より納得感を持って施策を進められます。
データ分析というと数学や分析の深い知識が必要そう…と構えてしまう印象ですが、日頃から自分の担当分野の基本的な数値を見ておくだけでもデザインで悩んだときの判断材料として使えるなど、デザイナーが数値をみる利点は多々あります。

分析の流れ

私は最近からデータ分析に取り組み始めたのですが、今はこのような流れで分析しています。

1.分析に必要な数値・グラフを決める

GitHubで分析用issueを立てて何を知りたいのか、そのためにはどんな数値をどんな形で見れると良いかを決めてから数値出しに進みます。

2.数値を出す

数値を出したらSQLが正しいかエンジニアにレビューしてもらいます。 レビューが通ったら数値から考えられることをチームで話しながら分析します。

3.分析レポートにまとめてGitHubのPull Request(以下PR)をだす

f:id:tsukasio:20170911145527p:plain

分析レポートを「仮説・試算・実数・考察・次のアクション」で整理してPRを出します。
レビューを受けることでさらに理解を深めるきっかけになったり、客観的な意見でアイディアをもらえたりします。
また、サービス開発部ではディレクター定例で施策の共有を行っていて、施策の分析結果はこのPRを共有しています。
ディレクター定例についてはこちらで詳しく説明されています。

つくれぽを簡単に送れる機能の分析

一部のユーザ向けに、よく見たレシピを利用したつくれぽを簡単に送れる機能を公開し、仮設通りの効果は得られたのか?どのように使われているのか?などを分析しました。

f:id:tsukasio:20170911145848p:plain

分析を進めていくうちに、アプリを起動してからつくれぽを送るまでの推移をファンネルグラフでみたところ、離脱ポイントが2つあることがわかりました。

  • 「投稿する」の分岐で離脱
  • レシピをフリックしてから離脱

f:id:tsukasio:20170911145750p:plain

まず「投稿する」の分岐での離脱はどんなユーザーが離脱しているのか調べました。結果はつくれぽを送ったことがないユーザーがほとんどで、興味本位で「投稿する」をタップしていた可能性がありそうです。
次に、つくれぽしようと思ってこの画面に来たのにフリックした後離脱してしまうのはなぜかを考えました。

  • つくれぽを送れるレシピがなかった
    • 実際には作っていなかった?
  • 料理画像がなかった
    • レシピをみて料理を作ったが料理画像を撮り忘れた?
  • つくれぽしようと思うレシピがわからなかった
    • 似たようなレシピが複数並んでいた?
    • レシピ名をきちんと覚えていなかった?

いくつか仮説を立てた中で、3つ目はUIで解決できそうだということになり改善を進めました。

UI改善

この機能のデザインをした時に考えたことは、新しい機能とはいえ、つくれぽを送るというアクションなのでユーザーが戸惑わないように既存のつくれぽ画面を参考にデザインしました。また、さくさく送れる感じを出したかったのでレシピをフリックして見れるようにしました。
ただ、既存のレシピ詳細画面からのつくれぽはすでにレシピを決めているので、つくれぽ画面ではレシピ名だけでもスムーズにつくれぽできていたという違いに気づきました。
この機能はつくれぽ送信画面に来てからつくれぽするレシピを探すので、どのレシピかがきちんと分かるUIが良いのではと思い、レシピ画像とレシピ作者名を入れたUIに変更しました。

before after
f:id:tsukasio:20170911150004p:plain f:id:tsukasio:20170911150637p:plain

まとめ

現在は施策を企画する段階とリリース後の2つのタイミングで定量データを見ることを心がけています。
漠然とした「使いづらい」「分かりづらい」から改善を進めるのではなく、定量的なデータからその機能がどう使われているかを把握した上で仮説を立てると、より良い改善に繋がります。
ただ数値がすべてというわけではなく、定量データから見えない課題はユーザーテストで掘り下げるなど定量分析・定性調査をバランスよく見ていくと良いと思います。

/* */ @import "/css/theme/report/report.css"; /* */ /* */ body{ background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527163350.png'); background-repeat: repeat-x; background-color:transparent; background-attachment: scroll; background-position: left top;} /* */ body{ border-top: 3px solid orange; color: #3c3c3c; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; line-height: 1.8; font-size: 16px; } a { text-decoration: underline; color: #693e1c; } a:hover { color: #80400e; text-decoration: underline; } .entry-title a{ color: rgb(176, 108, 28); cursor: auto; display: inline; font-family: 'Helvetica Neue', Helvetica, 'ヒラギノ角ゴ Pro W3', 'Hiragino Kaku Gothic Pro', Meiryo, Osaka, 'MS Pゴシック', sans-serif; font-size: 30px; font-weight: bold; height: auto; line-height: 40.5px; text-decoration: underline solid rgb(176, 108, 28); width: auto; line-height: 1.35; } .date a { color: #9b8b6c; font-size: 14px; text-decoration: none; font-weight: normal; } .urllist-title-link { font-size: 14px; } /* Recent Entries */ .recent-entries a{ color: #693e1c; } .recent-entries a:visited { color: #4d2200; text-decoration: none; } .hatena-module-recent-entries li { padding-bottom: 8px; border-bottom-width: 0px; } /*Widget*/ .hatena-module-body li { list-style-type: circle; } .hatena-module-body a{ text-decoration: none; } .hatena-module-body a:hover{ text-decoration: underline; } /* Widget name */ .hatena-module-title, .hatena-module-title a{ color: #b06c1c; margin-top: 20px; margin-bottom: 7px; } /* work frame*/ #container { width: 970px; text-align: center; margin: 0 auto; background: transparent; padding: 0 30px; } #wrapper { float: left; overflow: hidden; width: 660px; } #box2 { width: 240px; float: right; font-size: 14px; word-wrap: break-word; } /*#blog-title-inner{*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-position: left 0px;*/ /*}*/ /*.header-image-only #blog-title-inner {*/ /*background-repeat: no-repeat;*/ /*position: relative;*/ /*height: 200px;*/ /*display: none;*/ /*}*/ /*#blog-title {*/ /*margin-top: 3px;*/ /*height: 125px;*/ /*background-image: url('http://cdn-ak.f.st-hatena.com/images/fotolife/c/cookpadtech/20140527/20140527172848.png');*/ /*background-repeat: no-repeat;*/ /*background-position: left 0px;*/ /*}*/