Disentangled な表現の教師なし学習手法の検証

Keisuke Nakata

2019-10-08 11:20:57

本記事は、2019年インターンシップに参加された蕭喬仁さんによる寄稿です。


はじめまして。PFN の2019夏季インターンシップに参加した東京大学の蕭喬仁です。 大学では自然言語処理について研究しており、SNS からのマイニングに興味があります。
今回のインターンでは「Disentangled な表現の教師なし学習手法の検証 (Unsupervised Disentangled Representation Learning)」というテーマで研究を行いましたので、その紹介をいたします。

実験に使用したコードはこちら https://github.com/pfnet-research/chainer-disentanglement-lib で公開しています。

Disentangledな表現

映画 Star Wars がお好きな方は ”imperial entanglements” という表現でおなじみかもしれませんが、entangle とはもつれるという意味の英単語です。したがって Disentangled Representation とは直訳するともつれを解いた表現ということを指します。
では、もつれを解いた表現とは何なのでしょうか?実は disentangled な表現の定義は研究者の間でもまだ定まったものが無いのですが、多くの研究では潜在空間中の各次元が観測データ中の因子や性状ごとに分かれているような状態を disentangled な表現としています。たとえば、画像認識における disentangled な表現の各次元は被写体の「色」「形」「大きさ」などをそれぞれ表すことが期待されます。このような性質を持つ表現はある1つの次元を変動させても観測データ中の複数の要素が同時に変わる事が無いため、観測データの情報が解釈可能で低次元な潜在空間に圧縮された表現とも言えます。そのため教師有り・半教師有り学習などの機械学習タスクや few-shot learning, domain adaptation などに有用であるとされており、様々な手法が近年提案されてきました。

先行研究

教師なしで disentangled な表現を得る手法として state-of-the-art を主張している論文の多くは変分オートエンコーダ (Variational AutoEncoder; VAE) [1] をベースにした手法を採用しています。

図1. VAE の概念図

VAE では潜在変数の確率分布を標準正規分布に近づけながら学習を行いますが、disentangled な表現を得るためには潜在変数の事後分布がより標準正規分布に近い必要があります。データ \(X\) を生成している真の因子は各々独立であることを仮定しているからです。このような仮定のもと近年提案されてきた手法は VAE にどのような正則化項を加えるかで以下のように分類することができます。

  • 近似事後分布 \(q(z \mid x) \) をより事前分布である標準正規分布に近づける正則化項を加えた β-VAE [2]
  • aggregated variational posterior \(q(z) \) が各成分独立になるような正則化項を加えた FactorVAE [3] や β-TCVAE [4]
  • aggregated variational posterior \(q(z) \) が事前分布と近くなるような正則化項を加えた DIPVAE-1/DIPVAE-2 [5]

また、潜在変数に離散変数を使えるようにした、JointVAE [6] や CascadeVAE [7] などの手法もあります。

様々なモデルの提案と同時に disentangled な表現を定量的に評価する指標も数多く提案されています。評価指標には以下のような2系統が存在しますが、いずれの指標でも値の計算のためにデータの真の生成因子が必要となります。こちらでは紹介していませんが、インターンに参加していた8月中にも新しい評価指標 [8] が提案されており、どの指標を用いるべきかは研究者の間でも定まっていません。

  • データ \(X \) のある生成因子を固定した状態でその他の因子を変化させた時の潜在変数の変化をみる BetaVAE metric [2], FactorVAE metric [3], IRS [9]
  • エンコードした潜在変数から真の生成因子をどれだけ予測可能かをみる MIG [4], SAP-SCORE [5], DCI [10]

一方で、disentangled な表現を完全に教師無しで学習することは困難なのではないかという主張が最近なされるようになりました。Locattello らの研究 [11] では近年 state-of-the-art を主張してきた手法に対して大規模な検証実験を行い以下のようなことを示しています。

  1. モデルや正則化項等のハイパーパラメータよりも乱数による影響が大きいということ。
  2. モデルが学習した disentangled な表現が人間の直感に合う保証が無いこと。
  3. 再構成誤差や ELBO などの教師無しで得られるモデルの評価指標と教師有りの disentangled な表現の評価指標には相関が見られないこと。
  4. データ \(X \) を生成する確率 \(P(X) \) しか持っていない状況では、disentangled な潜在変数 \(p(z) \) と entangled な潜在変数 \(p(z^\prime) \) の識別が数学的に不可能であること。

ただし、論文では適切な帰納バイアスを取り入れることで教師ラベルを用いる事なく disentangled な表現を得ることは可能かもしれないとされており、別の論文 [12] でも損失関数に潜在変数の事前分布を適切に調整することでより良い disentangled な表現を得ることが可能であったという報告もされています。disentangled な表現を得る試みはまだまだ始まったばかりと言えるでしょう。

実験設定

今回のインターンでは、先行研究では検証されていなかった潜在変数の次元数や種類がパフォーマンスにどのような影響を与えるかを検証するために state-of-the-art を主張してきた BetaVAE, FactorVAE, DIPVAE-1/-2 に加えて離散変数を潜在変数として扱える JointVAE の Chainer 実装を行い、2つのデータセットを用いて実験をしました。モデル間で公平な比較を行うために、encoder/decoder の構造や optimizer・バッチサイズ・iteration の数などは共通にした上で、モデルごとに30個のシードで学習を実施しました。

本記事では代表的な実験結果として、データセットのうちの dSprites データに関する結果を紹介したいと思います。このデータセットにはハートや楕円などの物体がサイズや位置を変えて配置された2次元画像が納められており、データを生成する真の因子には物体の種類・物体の大きさ・物体の回転・x軸座標・y軸座標の5種類があります。

図2. データセットの例

実験設定1

上で紹介したモデルを使用する時にまず気になるのが潜在因子の次元数をどのように設定するべきかだと思います。そこで、今回は連続変数を潜在変数とする BetaVAE, FactorVAE, DIPVAE-1/-2 に関して、潜在変数の次元数を真の生成因子の数の半分・同じ・倍の3パターンのモデルを用意して学習結果を比較しました。

実験設定2

実務で使用する際には、dSprites データのように因子の全組み合わせに対応する網羅的なデータを用意することは現実的ではないことが考えられます。そこで、x座標と物体の大きさに相関ができるように因子の組み合わせを半分削除したデータと、比較対象として因子の組み合わせをランダムに半分削除したデータを dSprites データセットから人工的に作成し、パフォーマンスがどの程度落ちるのかを検証しました。

結果

実験1

以下に、潜在変数のある次元だけを動かして、その他の次元を固定した時にデータがどのように変化するかを見た latent traversal という図を掲載します。一番左の列は VAE に与えた元のデータを示しており、その右隣の画像は VAE による再構成画像です。その他の列は潜在変数中の各次元を \(-1.5 \) から \(1.5 \) まで動かした時の画像の変化を順番に描画しています。

 

潜在変数を3次元とした場合
BetaVAE
FactorVAE
DIPVAE-1
DIPVAE-2

 

潜在変数を5次元とした場合
BetaVAE
FactorVAE
DIPVAE-1
DIPVAE-2

 

潜在変数を10次元とした場合
BetaVAE
FactorVAE
DIPVAE-1
DIPVAE-2

 

潜在変数の次元数が小さい場合は、各画像の左から2番目、つまり再構成画像を見ると、どのモデルを使っても画像の再構成が上手くいかず、物体の形がぼやけてしまっているのが見て取れます。どうやら次元数を少なくしすぎるのは問題のようです。しかし、BetaVAE は潜在変数を大きくしても再構成があまり上手くいっておらず物体の形がぼやけてしまっています。実はこの問題は FactorVAE を提唱した論文でも述べられており、BetaVAE に観測データ \(X \) と潜在変数 \(Z \) の相互情報量を小さくするような効果があるから起きるとされています。次元数を真の生成因子と同じ5次元にした場合は、FactorVAE はx軸座標とy軸座標、サイズの変化を disentangle できていますが、DIPVAE-1/-2 では entangled された特徴が学習されてしまっています。次元数が10次元の場合も FactorVAE が5つの因子を disentangle できているのに対して、DIPVAE-1/-2 は直感的ではない特徴を学んでしまっているように見えます。次元数を真の生成因子の数よりも多くした場合は全てのモデルで latent traversal 上で動かない次元が出てきていますが、FactorVAE では真の生成因子の学習が上手くいっていることから、実務で使用する際には潜在変数の次元数は出来るだけ余分にとっておいたほうがいいことが推察されます。

実験2

以下では実験1で定性的に性能がよかった FactorVAE による結果を掲載しています。x座標と物体の大きさに相関があるデータで学習したものは、latent traversal 上でもx座標の移動とともに物体の大きさが変化していることがわかります。また、y軸方向の移動とともに物体の形状が変化しているのをみると、その他の因子の学習にも悪影響を及ぼしていてそうです。ランダムな欠損を与えたデータでは、完全なデータと同じレベルとまではいかないものの、ある程度は5つの因子を獲得できています。今回は全データの半分を削除したので、データを削除しすぎた可能性もあります。しかし、実務で使用する際に生成因子の全ての組み合わせのデータの準備が難しい場合は、せめて因子に相関がないようなデータに整えた上で学習を行うべきである事がこの結果から推察できます。

完全なデータ

x座標と物体の大きさに相関があるデータ
ランダムな欠損を与えたデータ

 

メンターからのコメント

メンターを担当した PFN の仲田と吉川です。

本文中でも触れられている通り、disentangled な表現の教師なし学習は few-shot learning や domain adaptation といった分野への応用や、機械学習モデルの解釈性の向上が期待できます。これらは現実世界への機械学習の適用をする際にいつも直面する課題です。
深層学習などの先端技術による現実世界の課題解決をミッションとする PFN としても以前から取り組んではいるのですが、タスク自体の難しさはもちろん、問題設定をおこなうことも難しい分野です。インターン期間中は手法の再現性や各種文献の実装の読解などにお互い苦労しましたが、最終的には代表的な手法を一通り Chainer で実装し、様々なデータやパラメータ、評価指標を広く調査して頂いた蕭さんの今回の成果は、今後の PFN における研究開発にあたっての足がかりとなることと思います。

参考文献

PFNが提供する教育コンテンツについて

Hiroshi Maruyama

2019-10-07 15:38:56

PFNフェローの丸山(宏)です。2月にプログラミング教育についてのブログを書きました。またそれに合わせて制作した教材を利用して、6月に弊社カフェテリアで、小学生を対象にした体験教室を開催しました。この体験教室については、丸山(史郎)がロボットカーの体験教室について西澤が火星語翻訳を題材にした教材について書いています。今回、山梨大学と共同で、高専・大学学部向けの教材 ロボットカーで学ぶ深層学習の基礎 を開発しました。このブログでは、これら一連の教育関連の活動について、その意義と全体像をもう一度整理してみたいと思います。

また、付録に、現在PFNが提供する教育用コンテンツのリストがありますので、そちらもご利用ください。

古典的プログラミング

2016年に文部科学省が主宰する「小学校段階における論理的思考力や創造性、問題解決能力等の育成とプログラミング教育に関する有識者会議」は、議論の取りまとめを公表し、その中で

自分が意図する一連の活動を実現するために、どのような動きの組合せが必要であり、一つ一つの動きに対応した記号を、どのように組み合わせたらいいのか、記号の組合せをどのように改善していけば、より意図した活動に近づくのか、といったことを論理的に考えていく力

プログラミング的思考と呼び、それをこれからの時代における普遍的な能力として教育課程に組み込んでいく必要を訴えました。ここで言う「プログラミング」は、アルゴリズムを実行するステップを明示的に書き下すタイプの通常のプログラミングで、このようなプログラミング作られたソフトウェアをここでは古典的ソフトウェアと呼ぶことにしましょう。

ソフトウェア2.0

古典的プログラミングでは、「計算機にやってほしいこと」を記述するのに、計算のステップを明示的に計算機に指示するプログラミング方法しかありませんでした。しかし、それが計算機に対する唯一のプログラミング方法でしょうか。深層学習による帰納的プログラミングにおいては、入出力の例示(訓練データセット)を与えることによって「やってほしいこと」を記述します。Optunaのようなベイズ最適化ツールは最大化(最小化)したい関数の、特定の点の値を返す「オラクル」を記述することによって「やってほしいこと」を記述します。どちらも、計算のステップは記述しません。このようなプログラミングによるソフトウェアをTeslaのAndrej Karpathy氏はソフトウェア2.0と呼んでいます。

ソフトウェア2.0では、計算機内部で実行されるアルゴリズムを知らなくても構いません。「やってほしいこと」を伝える方法さえ知っていれば計算機というツールを使うことができのです。たとえば乗換案内というツールを考えてみましょう。「やりたいこと」は出発地と目的地を指定することで伝えることができます。場合によっては、航空便を使わない、とか時間よりも価格を重視する、とかの最適化もできます。乗換案内を実装している中のアルゴリズムをご存知でしょうか。基本は初期の人工知能研究の成果、たとえば手段目的分析(means-end analysis)などの探索アルゴリズムのようなものだと思います(私は中身を見たわけではないので、想像にすぎません)が、中身を知らなくても乗換案内を効果的に使うことができます。

乗換案内のような道具を使う際に大事なのは、その中身がどのようなメカニズムで実装されているかではなく、それが提供する機能、すなわち「A地点からB地点まで移動する最短時間(最短コスト)の経路を表示する」というものだと思います。機能さえ知っていれば、中のメカニズムを知らなくても使えるのです。私達が毎日使っているテレビ、スマホ、電車などは、その機能はよく知っていますが、中のメカニズムを正確に知っている人はほとんどいないと思います。それでも上手に使えます。同様に、これからの計算機は、古典的プログラミングを知らなくても、深層学習やベイズ最適化の「機能」だけ知っていれば使える時代が来るのだと思います。

小学生に対して私たちが教育コンテンツを提供するのは、このような未来を想定しているからです。

深層学習の正しい理解と普及

長期的には「やってほしいこと」を記述するだけのソフトウェア2.0的なプログラミングが可能になると思いますが、一方で、直近では深層学習という新しい技術を正しく理解し、社会問題の解決に効果的に使っていくスキルが求められます。深層学習は人工知能研究における偉大なブレークスルーですが、それだけで人間の知性のような、いわゆる「汎用人工知能」が実現できるわけではありません。ホーキング博士が言う「人間を超えるAI」は、まだSFの世界の話であり、現在の深層学習技術の延長上にはない、というのが多くの人工知能研究者の意見です。深層学習にできること、できないことを正しく理解し、それを等身大に発信していくことが私たちには求められています。

PFNが提供する「ディープラーニング入門 Chainerチュートリアル」などの教育コンテンツは、これは社会で実際に深層学習を利用する社会人の方々、あるいは卒業後にそのような職種につきたいという大学生・大学院生の方々に対して、この技術を正しく理解して、正しく有効に活用していただきたい、という意図で提供しているものです。このため、深層学習のベースとなる数学や確率・統計の理解を含め、記述の正確性に重点を置いたコンテンツになっています。

今回山梨大学の牧野先生・西﨑先生と共同で作らせていただいたコンテンツは、より間口を広くして、高等専門学校から大学学部レベルの学生の方々に、深層学習に興味を持っていただく内容になっています。このため、レゴ(R) マインドストーム(R) EV3というロボットカーを実際に深層学習で制御して走らせてみる、というハンズオンスタイルの教材になっています。また、ルールベースの古典的プログラミングと深層学習によるSoftware2.0のプログラミングを対比して学べるようになっています。深層学習の訓練(学習)を含めすべてのPythonプログラミングがRaspberry Pi上で完結するように設計されていて、クラウドに依存することなく、授業を実施することができます。このあたりは、ワークショップ型の授業の経験豊富な牧野先生・西﨑先生のノウハウが存分に活かされています。

今後もPFNは、将来を見通して、社会にとって必要な教育コンテンツを、初等教育からリカレント教育まで幅広く提供していきます。

PFN提供教育用コンテンツ一覧

いずれのコンテンツも、自習や学校での授業には自由にお使いいただけます。

大学・大学院・社会人向け

高校・高専・大学学部向け

初等教育向け 

 

微分可能なMPCのChainer実装および追加実験

Yo Iida

2019-10-04 14:30:30

本記事は、2019年インターンシップとして勤務した新幡 駿さんによる寄稿です。


こんにちは、2019年夏にPFNでインターンをしていた新幡です。大学では連続最適化の研究室に所属しています。PFNではモデル予測制御 (MPC; Model Predictive Control) を「微分可能」にするAmosら (2018) の論文“Differentiable MPC for End-to-end Planning and Control”[1] について、著者によるPyTorch実装のChainerへの移植と追加実験を行いました。MPCはモデルを用いて将来の状態を予測しながら制御を行う手法であり、化学プラントの制御などに用いられています。

【2019/10/7追記】Chainerへの移植実装はGitHubで公開しています。
https://github.com/pfnet-research/chainer-differentiable-mpc

1. OptNet

Amosらは、2017年に二次計画法を微分可能にする層として“OptNet: differentiable optimization as a layer in neural networks”[2] を提案しました。二次計画法を微分可能にすることで、勾配降下法を用いて二次計画法の目的関数や制約条件を、ネットワークの損失関数に対して最適化することができます。OptNetの順伝播は、二次計画問題を主双対内点法という収束するまで反復を繰り返す方法を用いて解いていますOptNetの誤差逆伝播は、主双対内点法を全て連鎖律で逆にたどるのではなく、最適解の満たすべき条件のうち等式で書けるもの (KKT行列) から効率的に偏微分を求めています。大量のデータを用いて学習する為に、二次計画問題を大量に解く必要があるので、Amosらはバッチで計算できるような主双対内点法を実装しており、著者実装は A fast and differentiable QP solver for PyTorch として公開されています。また、副メンターの酒井さんによるChainerへの移植の試みとして chainer-optnet があります

図1. OptNetの概要図

2. Differentiable MPC

OptNetで二次計画法を微分可能にする手法が提案されたので、有限離散時間線形二次レギュレータ (Linear-Quadratic Regulator; LQR) などの二次計画法を用いて解ける最適制御問題はOptNetを用いて微分可能にできます。しかし、LQR二次計画問題として解くのではなく、動的計画法を用いた方が効率的に解くことができることが知られています。Amosらは、LQRの順伝播の計算に動的計画法を用い、誤差逆伝播の計算もKKT行列の時間的構造を用いてOptNetより効率的に微分を求められるLQRを提案しました。

さらに有限離散時間MPCのようなコスト関数やダイナミクスが非線形な問題に対しても、微分可能にした論文がAmosらによるDifferentiable MPCです。著者による実装はアルゴリズムの主な部分が mpc.pytorch としてライブラリになっており、著者の実験コードは differentiable-mpc といレポジトリにあります。

3. 前提知識

3.1. LQR

LQRは一般的には、コスト関数が二次でダイナミクスの制約が線形、操作量が無制約な次のような形で表される最適制御問題です。

$$
\begin{align*}
&\underset{\tau_{1:T}}{\text{minimize}} & & \sum_t \frac{1}{2} \tau^T_t C_t \tau_t+c^T_t \tau_t \\
&\text{subject to} & & x_1 = x_\text{init}\\
& & & x_{t+1} = F_t \tau_t + f_t
\end{align*}
$$

ここで \(x\) は状態、 \(\tau\) は状態と操作量を連結したもの、 \(C\) はコスト関数の二次の項を表す行列、 \(c\) はコスト関数の1次の項を表すベクトル、\(F\) はダイナミクスを表す行列になります。Amosらは、LQRを動的計画法を用いて、ベルマン方程式を再帰的に解くことで解いています。詳しくは[3]を参照してください。

3.2. MPC

MPCはLQRと異なり、コスト関数は2次に限らず、ダイナミクスも線形に限りません。さらに、操作量に制約がつく場合もあります。元論文で扱ったMPCは以下の式です。

$$
\begin{align*}
&\underset{\tau_{1:T}}{\text{minimize}} && \sum_t C_{\theta, t}(\tau_t) \\
& \text{subject to } && x_1= x_{\mathrm{init}}\\
&&& x_{t+1} = f_{\theta}(\tau_t)\\
&&& \underline{u} \leq u \leq \overline{u}
\end{align*}
$$

Amosらは、コスト関数を二次近似、ダイナミクスを一次近似して、収束するまでLQRソルバを繰り返し用いるiLQRという手法を用いて解いています。また、制約については、Tassaら (2012) による“Control-Limited Differential Dynamic Programming”[4] と同じように扱っています。

4. 応用

Differentiable MPCの応用として、Amosらが行っているのがエキスパートの操作列を模倣する模倣学習 (imitation learning) です。Amosらによる模倣学習は、ダイナミクスやコスト関数をパラメータ化した形で表して、エキスパートの操作列との二乗誤差をネットワークの損失関数としてパラメータを最適化させています。最適化によって得られたダイナミクスやコスト関数をMPCに用いることで、エキスパートの操作列を模倣する方策を得られると期待できます。Amosらは、実験設定として、倒立振子 (inverted pendulum) を題材に、学習するものがダイナミクスのパラメータのみ・コスト関数のパラメータのみ・両方の三通りの学習を試しています。

図2. 模倣学習の設定

例として、ダイナミクスを既知として、コスト関数をパラメータ化した形で学習を行うと次のようになります。エキスパートの操作列から、正しく倒立振子を安定化させることができていることがわかります。

図3. 学習したコスト関数を用いた制御

5. 追加実験

追加実験として、コスト関数をAmosらのように特定の形にパラメータ化した形ではなく一般の二次関数の場合もうまく学習できるのかを試しました。ここでAmosらのパラメータ化を詳しく説明すると、以下の数式のようになっていて、\(q_{\text{logit}}\)と\(p\)という二つのベクトルをパラメータとしています。

$$
\begin{align*}
q &= \mathrm{sigmoid}(q_{\rm{logit}})\\
C(\tau) &= \frac{1}{2}\tau^T q \tau + (\sqrt{q} \circ p)^T \tau
\end{align*}
$$

追加実験として試したパラメータ化は、半正定値行列\(Q\)とベクトル\(p\)をパラメータとして用いてコスト関数をより多くのパラメータで表現しています。

$$
\begin{align*}
C(\tau) = \frac{1}{2}\tau^T Q \tau + p\tau
\end{align*}
$$

5.1. 真のコスト関数がAmosらのパラメータ化で表現できる場合

図4. 真のコスト関数がAmosらのパラメータ化で表現できる時

この場合は、真のコスト関数の構造を取りいれているAmosらによる手法の方が損失関数の値が下がりました。

5.2. 真のコスト関数がAmosらのパラメータ化で表現できない場合

真のコスト関数がAmosらのパラメータ化で表せないように問題設定を変えました。

この場合、一般的な二次関数のパラメータを用いた手法とAmosらの手法を比較すると、損失関数がどの程度まで下がるかは同等でしたAmosらの手法では、真のコスト関数を表現できないので、一般的な二次関数を用いて学習させる方が損失関数の値が下がることを期待していたのですが、これは意外な結果でした。Amosらは、LQRの場合に、ダイナミクスを一般的な行列の形にして模倣学習を行い、その際は半分程度は損失関数がうまく下がらないという現象を確認していますが、これを模倣学習の損失関数が、ダイナミクスのパラメータに対して、勾配降下法では最適化することが難しい非凸な関数であったからと結論づけています。今回、一般的な形のコスト関数でうまく学習できなかったのも、コスト関数を一般的な形にすると、損失関数がコスト関数のパラメータに対して非凸な関数になったからではないかと考えられます。

図5. 真のコスト関数がAmosのパラメータ化で表現できない時

6. 感想

今回のインターンでは、Differentiable MPCのChainerへの移植を行い、色々と実験設定を変えてみました。コスト関数を凸なニューラルネットワークで置き換えられるとおもしろそうだなという思いつきから、まずはコスト関数のパラメータを増やして実験してみました。元論文では模倣学習の損失関数が制御器のパラメータに関して非凸な関数になることがあると指摘されており、追加実験でもパラメータを増やしたところあまり損失関数の値が下がらないという結果になりました。

Differentiable MPCは理論、実装共にかなり複雑で、Chainerにライブラリを移植するのにかなり苦労し、時間がかかってしまいましたが、メンターさん方の助けもあってなんとかできました。ありがとうございました。

参考文献

[1] B. Amos, I. Jimenez, J. Sacks, B. Boots, and Z. Kolter. “Differentiable MPC for End-to-end Planning and Control” In NIPS’18 Proceedings of Advances in Neural Information Processing Systems. Available: https://arxiv.org/abs/1810.13400

[2] Brandon Amos, and J. Zico Kolter, “OptNet: differentiable optimization as a layer in neural networks” In ICML’17 Proceedings of the 34th International Conference on Machine Learning. Available: https://arxiv.org/abs/1703.00443

[3] Sergey Levine.  Optimal control and planning. berkeley cs 294-112:  Deep reinforcement learning. Available: http://rail.eecs.berkeley.edu/deeprlcourse-fa17/f17docs/lecture_8_model_based_planning.pdf

[4] Yuval Tassa, Nicolas Mansard and Emo Todorov. “Control-Limited Differential Dynamic Programming” ICRA’14 IEEE International Conference on Robotics and Automation. Available: https://homes.cs.washington.edu/~todorov/papers/TassaICRA14.pdf


メンターからのコメント

メンターを担当したPFNの飯田と酒井です。

PFNは深層学習に強みがありますが、現実の問題を解決するには深層学習だけでは不十分なこともあり、最適化や制御の技術を組み合わせて用いることも多いです。しかし、昨年までのインターンシップではそういったバックグラウンドの学生の方にはあまりリーチ出来ていませんでした。

そこで、今年のインターンシップ募集でのテーマ「機械学習アルゴリズムの応用 (数理最適化、シミュレーション、時系列予測など) に関する研究開発」では「数理最適化」もキーワードに含め、結果として最適化のバックグラウンドを持つ学生さんとの研究開発を幾つか実施することができました。微分可能MPCに関するこのテーマはその一つです。

今回のテーマは、再現実装の負荷がメンター二人の想定していたよりも重く、新幡さんには随分苦労させてしまいましたが、再現実装と追加実験までを行っていただくことができました。社内の他のプロジェクトでも深層学習とMPCを組み合わせて用いており、今回の新幡さんの成果も今後それらにうまく活用していきたいと考えています。

スポーツ映像に対するシーンのアノテーション効率化

Tatsuya Takamura

2019-10-02 12:03:57

本記事は、2019年インターンシップとして勤務した佐々木 克仁さんによる寄稿です。


はじめまして。PFNの2019年夏季インターンシップに参加させていただいた東京大学修士1年の佐々木克仁です。大学ではHCIの研究をしています。WEB開発が好きです。

テーマとその背景

今回のインターンシップで私が取り組んだ研究テーマは「スポーツ映像に対するシーンのアノテーション効率化」です。

PFNでは、スポーツ映像の中でチームが取っている戦術を推定し、スポーツの戦術解析に応用するシステムを開発しています。このような推定を実現する機械学習モデルを学習するためには、チームが取っている戦術とその時間範囲(以降シーンと呼びます)がスポーツ映像にアノテーションされた大量のデータセットが要求されます。しかし、スポーツ映像におけるシーンの戦術レベルでの詳細な区別を一般の人々が行うのは困難で、そのスポーツに精通した専門家しかアノテーションできず、彼らの限られたリソースを効率的に利用するためにアノテーションの効率化が必要となります。

今回私が着目したのは「シーンの境界線を決めるのに時間がかかっている」という課題でした。アノテーターは先頭からスポーツ映像を見ていって各シーン間の境界線の時間を記録することでアノテーションしていきます。境界線はルールに基づいて決定するのですが、この作業に時間がかかっており、またアノテーターのストレスに繋がっています。インターンシップではこの課題を解決するための取り組みを行いました。

手法

私が取り組んだ手法では、各シーンに対してアノテーターは「シーンの境界線を決める」代わりに「シーンの中の適当な一時点を決める」作業を行います。これによってシーンの境界線を決める労力が削減されるためアノテーションが効率化されると考えられます。以降では「シーンの境界線を決める」アノテーションを「Boundary型」、「シーンの中の適当な一時点を決める」アノテーションを「Timestamp型」と呼びます。Timestamp型アノテーションの考え方は[1]から取り入れました。

annotation-image

図1: アノテーターはシーンの中の適当な一時点を決める

しかし、Timestamp型のアノテーションはそのままデータセットとして利用することはできず、一つのTimestampを元にそのTimestampが示すシーンの境界線を推定する必要があります。そこで今回は、学習させた機械学習モデルの反応を見て、与えられたTimestampを元に暫定的に決めた境界線から徐々に境界線を更新させるという方法を採用しました(図2)。境界線の更新と機械学習モデルの学習を並行して行うことで、相互に作用しながら解に近づいていきます。

iteration

図2: Timestampから境界線を推定する手法の概要

境界線は、機械学習モデルが出力した各クラスの確率分布に基づいて更新されます(図3)。図2は、クラスAとクラスBのシーンの境界線を示しています。現在の境界線(点線)において機械学習モデルが出力したAの確率とBの確率の差Δが、閾値よりも大きい場合に境界線をB方向に更新します。更新の大きさは、Aの確率を示す曲線とBの確率を示す曲線の交点を基準に学習率をかけたものとなります:

eq1

ここで、bは境界線の時刻、cは曲線の交点の時刻、rは学習率です。

boundary-update

図3: 境界線の更新

この境界線の更新手法は、[2]を参考にして改良を加えたものになっています。[1]の方法は、Backgroundクラスが大部分を占めるAction Recognitionのタスクでは有効ですが、スポーツ映像のようなほぼ全てのフレームがBackgroundでないクラスを持つタスクではうまく機能しないと考えられるため採用しませんでした。

実験・評価

境界線の推定精度

まず、境界線を推定する手法が適切に機能するかどうかをシミュレーションによって評価しました。アノテーターによるTimestamp型アノテーションのシミュレーションを、Ground-Truthのデータにおけるそれぞれのシーンの時間範囲からガウス分布に基づいてサンプリングすることで行います。推定された境界線の精度は、Ground-Truthの境界線と推定された境界線のIoU(Intersection over Union)によって評価しました。IoUは2つの領域が重なっている割合を示す値であり、IoUが高いほど境界線の推定精度が高いことを示しています。

以下に結果を示します(図4)。「学習→境界線の更新」の繰り返しを行うたびにIoUの平均値が向上することが示されています。最終的に0.76まで到達しています。今回推定された境界線に基づいたデータセットの有用性の検証は今後の課題となります。

estimated boundary

図4: IoUの平均値(横軸は境界線の更新回数)

Timestamp型アノテーションの効率

次に、Timestamp型アノテーションによって実際にアノテーションの速度が向上することをユーザースタディによって検証しました。ユーザースタディに向けてBoundary型とTimestamp型のWEBインターフェースを実装しました(図5)。被験者としてスポーツ解析の専門家2人にご協力いただきました。被験者は制限時間内に可能な限りのアノテーションを行い、それぞれの方式でアノテーションできる数を比較します。今回は被験者数が十分ではありませんが、初期検討の材料としての実験とし、追加実験は今後の取り組みとします。

compare mode

図5: アノテーションツールの実装(左はBoundary型、右はTimestamp型)
※スポーツ映像の部分はイメージ図です

ユーザースタディの結果、Timestamp型ではBoundary型の約2倍の速度でアノテーションできることが分かりました。アノテーションが速くなった原因としては、当初想定していた境界線を決める時間が削減されたこと以外にも、Timestamp型のほうがツールとして操作が容易であったこともあるようでした。被験者となっていただいた専門家の方からは「直感的」「映像を見ている感覚でできるのでストレスが少ない」という今回の手法に対する肯定的なフィードバックをいただくことができました。一方で、アノテーターによってシーンの中のどのタイミングでアノテーションするかの傾向が異なるという課題も発見されました。シーンの中のどのタイミングでアノテーションするるかは境界線の推定における初期値を決める重要な因子です。ユーザスタディを実際に行ったからこそ判明した重要な発見でした。

研究のまとめ

今回の研究では、スポーツ映像に対するシーンのアノテーションを効率化するための手法として、Timestamp型のアノテーションに取り組みました。Timestampからシーンの境界線を推定する手法では、Ground-Truthと比較してIoUで0.76の精度を実現しました。また、スポーツ解析の専門家2名によるユーザースタディによってTimestamp型のアノテーションでは従来の方式より2倍速くアノテーションできることが分かりました。今後の課題としては、シーンの境界線推定の精度が得られた結果で十分であるかどうか検証する必要があり、またユーザによるアノテーションのタイミングのばらつきに対処する必要があります。

インターンシップの感想・謝辞

今回2ヶ月間のインターンシップに参加させていただき、非常に充実した時間を過ごすことができました。2ヶ月もの間1つの研究について考え続けるのはとても楽しく、かつてない経験をさせていただきました。PFN社員の方々のレベルが非常に高く、せっかくこの環境にいるのだから難しい問題に取り組んでみようと前向きな気持ちでチャレンジすることができました。また、インターンの同期も同世代と思えないほど実力のある人ばかりで自分の至らない部分を知ることができ、多大な刺激を受けました。本当に参加してよかったと思えるインターンシップでした。

最後に、メンターをはじめとしたチームの皆さま、研究のサポートをして頂き誠にありがとうございました。また、ポスターセッションでフィードバックをくださった皆さま、適切な助言をありがとうございました。

参考文献

[1] Moltisanti, Davide, Sanja Fidler, and Dima Damen. “Action Recognition from Single Timestamp Supervision in Untrimmed Videos.” Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2019.

[2] Ding, Li, and Chenliang Xu. “Weakly-supervised action segmentation with iterative soft boundary assignment.” Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2018.

Chainer Chemistryの大規模グラフのタスクへの拡張

Kosuke Nakago

2019-10-01 13:09:08

本記事は、2019年インターンシップで勤務した 阿部健信 さんによる寄稿です。

こんにちは。2019年夏季インターンに参加した東京大学の阿部健信です。「Chainer Chemistryの大規模グラフのタスクへの拡張」というテーマで取り組んだ内容を説明させていただきます。インターン内容のスライドはこちらにアップロードされています。

PFN Summer Internship 2019 / Kenshin Abe: Extension of Chainer-Chemistry for Large and Sparse Graph from Preferred Networks

 

TLDR;

  • Chainer Chemistryで大規模グラフのデータを扱えるようにしました。
  • convolution演算を\( O(V^2) \)から\( O(E) \)にしました。
  • メモリ使用量も抑えて、PyTorch Geometricでは動かないRedditデータセット(23万頂点, 1100万辺)を16GBのsingle GPU上で学習できるようにしました。

 

はじめに

 

graph convolution [1]

画像に対する2D ConvolutionとGraph Convolutionの比較 [1]

入力としてグラフを受け取ることのできる、Graph Neural Network(GNN)という分野が近年注目を集めています。
その注目の高まりから、PyTorch Geometric [2]やDeep Graph Library (DGL) [3]といった高機能で最適化されたGNNライブラリの開発が盛んに進められています。

Chainer Chemistryは、PFNが開発しているGNNのオープンソースのライブラリです。
名前からも分かるとおり、もともと分子など化学データへの適用を目的として作られたもので、qm9などの化学データセットが手厚くサポートされています。一方、他にGNNの研究でよく用いられるSNSなどのネットワークデータのサポートはなされていませんでした。

 

課題内容

今回のインターンのタスクは、Chainer Chemistryでネットワークデータのサポートを行うことです。そのために、大きく以下の2つの内容を行いました。

1. node classificationのサポート
化学分子データなどたくさんの小さなグラフのデータセットに対してGNNは、graph classification/regressionといった、グラフ全体の性質を学習するのに用いられます。
一方、巨大なネットワークデータに対しては、1つのグラフを入力として各頂点ラベルの分類を行うといった異なるタスクに用いられる事が多いです。
[4]で提案されているようなsemi-supervised node classificationへの対応を行いました。
具体的なフレームワークの違いはスライドをご参照ください。

2. 巨大でsparseなグラフのためのGNNの効率的な実装
こちらが今回のインターン内容のメインで、巨大なグラフを動かすためには必要不可欠な内容でした。
以下、\( V \) 個の頂点、\( E \)個の辺からなるグラフを考えます。
Message passingにもとづくGNNでは、各頂点に対して近傍の頂点の特徴量のaggregationの操作を行います。このaggregationの関数はpermutation invariantな様々な関数が用いられ、例えばよく使われるsumの場合は以下の式になります。
\( H’ = AH \)
(\( H \): 頂点の特徴量行列, \( A \): 隣接行列, \( H’ \): aggregateされた特徴量)

既存の実装は全てこの行列演算に基づくものでしたが、これは2つ問題点があります。
1つめは、グラフが疎な際にメモリ的にも実行時間的にも無駄が生じてしまうことです。
2つめは、batch化の際のゼロパディングのオーバーヘッドです。

これらの問題を解決するために、辺の情報を密な隣接行列ではなく、疎なデータ形式で持たせるという事が考えられます。今回のインターンでは、こちらのレポジトリでsparse patternとして紹介されているデータの持ち方を新たに実装しました。
これは辺の情報を\( [2, E] \)のサイズの行列で持つ手法で、PyTorch Geometricでも採用されています。

Sparse patternでは、scatter演算と呼ばれる命令を用いることでaggregation部分の計算量を\( O(E) \)で行うことができます。
またbatch化の際に、複数のグラフを全体として大きな1つのグラフとしてみなすことによってゼロパディングのオーバーヘッド完全になくすことができます。
こちらも、より詳細な手法が知りたい方はスライドをご覧ください。

 

結果

行列演算による既存実装と、sparse patternによる実装の速度比較は以下のようになりました。
まず、3312頂点、4660辺の疎なネットワークグラフに対しては、CPUでは50倍以上、行列演算との相性が良いGPU上でも2倍以上の速度改善が見られました。
また、1つ予想外だったのは、最大でも38頂点という比較的小さなグラフからなる化学データセットに対してもGPU上でも1.5倍程度の速度改善が見られたことです。
これには、バッチ化のオーバーヘッドをなくす工夫が効いていると考えられます。

sparse patternはグラフのconvolution演算に特化して実装されているため速いもののメモリ使用量にまだ無駄があり、Redditデータセット(23万頂点, 1100万辺)を動かすことはできませんでした。
これについては、ChainerのサポートしているCooMatrix演算によるモデルを用いたところsingle GPU (16GB)で動かすことができました。

これまで触れた、既存の隣接行列・sparse pattern・CooMatrixの3パターンについてまとめると、グラフが疎であったりバッチ化のオーバーヘッドが大きかったりすれば基本的にsparse patternが早く、それではメモリが足りない場合はCooMatrixを使うとよい、という結果になりました。
この結果を踏まえて、3つのパターンを場合に応じて使い分けられるように実装しています。
特に、現状のPyTorch Geometricでは動かすことができないredditなどの超巨大なグラフを動かせるという点は、Chainer Chemistryを使うモチベーションの1つになると思います。
新しいモデルを自分で実装したいときに、ChainerでサポートされているCooMatrix演算を普通の行列演算と同じようなインターフェースで直感的に使えるのも魅力です。

 

 

まとめ

今回の成果はChainer Chemistryにマージされています。新しい実装方針に対応しているモデルはまだ多くはありませんが、これからどんどん対応していく予定です。
exampleのコードを動かすことで簡単に巨大グラフ上での学習ができるようになっているので、ぜひ試してみてください。

 

参考資料

[1] https://arxiv.org/pdf/1901.00596.pdf
[2] https://rlgm.github.io/papers/2.pdf
[3] https://rlgm.github.io/papers/49.pdf
[4] https://arxiv.org/pdf/1609.02907.pdf

 

視覚からの触覚特性の推定 (ICRA2019 Best Conference Paper Award Finalist)

Kuniyuki Takahashi

2019-09-30 09:49:25

リサーチャーの高橋城志(Takahashi Kuniyuki)です.

2019年5月にロボティクス分野のトップ会議であるICRA2019が開催されました.そこに投稿された約2900件の論文から3件だけ選ばれるBest Conference Paper Award Finalistを受賞しました.この論文はリサーチャーのJethro Tanと執筆したもので,その紹介をします.論文,動画,データセットは下記から閲覧できます.

論文タイトル:Deep visuo-tactile learning: Estimation of Tactile Properties from Images

論文のリンク:https://arxiv.org/abs/1803.03435

データセット:https://github.com/pfnet-research/Deep_visuo-tactile_learning_ICRA2019

論文の動画:https://www.youtube.com/watch?v=ys0QtKVVlOQ&feature=youtu.be

視覚からの触覚特性の推定

 Fig. 1に物体の写真を何枚か載せています.人は物体の表面を触ることで,柔らかさや粗さといった触覚特性を知覚することができます.また,画像だけから触覚の特性とその度合い(e.g. 柔らかさとその程度)を推定できます.この能力は物体操作や歩行方法などの判断に必要になります.例えば,柔らかそうなものは優しく把持を行い,滑りそうな床では気をつけて歩くなどです.

Fig. 1 視覚からの触覚特性の推定

関連研究

 これまでの方法では,触覚特性やその度合を手動でラベル付けする,教師あり学習がほとんどでした.しかし,この方法では手動でつけられたラベルの種類や粒度に結果が依存することになります(Fig. 1).特性の種類(e.g. 柔らかさ,滑らかさ,べたつき)やどの程度の粒度を用意するかは事前に決めなければならなず,手動でのラベル付けで想定していない未知の物体や粒度に対しては,既存のラベルに割り振られてしまうという課題があります.

Deep visuo-tactile learning

 そこで,手動でのラベル付けをせずに,教師なし学習で触覚の特徴を獲得する,deep visuo-tactile learningを提案します(Fig. 2).このモデルはエンコーダ・デコーダ型の深層学習の入力を画像情報,出力を触覚情報を用いており,潜在変数に触覚特性を獲得させます.出力は教師信号がある教師あり学習ですが,潜在変数には教師がないため,触覚特性の獲得に関しては教師なし学習です.

Fig. 2 Deep visuo-tactile learning

 このモデルの学習後,潜在変数に触覚特性が連続値として表現されることになります.そのため,度合いの粒度を事前に決める必要がありません.物体の触覚特性の推論には,対象となる物体の画像を入力するだけで物体の触覚特性である潜在変数が得られます(Fig. 3).つまり,触覚センサは学習にのみ必要で,学習後の推論には触覚センサを必要としません.触覚センサは高価で壊れやすいため,触覚センサを使わずに触覚の特性を推論できるという利点があります.さらに,シミュレーションでは接触状態を扱うのが困難で,触覚情報を扱うことは難しいですが,本手法ではシミュレーションでの画像から触覚情報の推定も可能となります.

Fig. 3 学習後のDeep visuo-tactile learning

データセットの作成

モデルの評価のため,25種類の物体を用いて,新たなデータセットを作成しました(Fig. 4).このデータセットは公開していて,自由に使用できます.
https://github.com/pfnet-research/Deep_visuo-tactile_learning_ICRA2019
実験には,Sawyerと呼ばれる7自由度の腕を持ったロボット,及び,その手先にウェブカメラとuSkinと呼ばれる触覚センサを取り付けたものを使用しました.uSkinは16点のそれぞれのセルで圧力方向とせん断方向の力を取得できます.ロボットは物体表面をなぞる動作を行い,そのときの画像と触覚センサのデータを取得します.実際に取得した時系列における触覚センサの各セルの圧力方向とせん断方向の力のグラフをFig. 4に示します.

Fig. 4 データセット作成

評価実験:潜在変数の可視化

 作成したデータセットを学習させて,触覚センサの特性が表現されている潜在変数を可視化したものをFig. 5に示しています.図中の赤色の星は学習に使用した物体で,青色は学習に使用していない未知物体です.取得した触覚センサの値から,物体の摩擦が大きいほど緑色の円の色が濃くなるように描画しています.Fig. 5から布でない物体はLatent varialbe 1の軸の低い値にプロットされる一方,布の物体は高い値でプロットされていることが分かります.これは,触覚センサの表面を布で覆っていたため,触覚センサ表面の布と布の物体との摩擦が大きくなったためだと考えられます.このことから,潜在変数には摩擦情報が表現されていることが示されました.

Fig. 5 摩擦を表現したLatent Variable

 Fig. 5と同じ方法で,センサ情報から硬くて粗い物体ほど円の緑色が濃くなるように描画したものをFig. 6に示しています.図から硬くて粗い物体であるほど,Latent variable 2の軸において小さな値にプロットされていることが分かります.例えば,カーペットは硬くて粗いですが,バスタオルは柔らかくて滑らかと認識されています.また,色のみ異なる物体や似ている物体は近い位置でプロットされていることが分かります.このことから潜在変数に触覚の特性として柔らかさと硬さが表現されていることが示されました.

 本手法の性能限界を調べるため,紙に印刷された畳の画像から触覚特性を推論させました.その結果,印刷された畳は硬くて粗い物体と認識されていますが,本来推定するべきものは紙であるため,実際の特徴とは異なります.今回の手法では入力としては画像のみを使ったために生じた問題です.深さ情報まで含めた入力にすることで,物体表面の形状情報が取得できるようになるため,このような問題を解決できると考えています.

Fig. 6柔らかさと粗さを表現したLatent Variable

まとめ

画像からの触覚特性とその度合を推定するために,教師なし学習であるdeep visuo-tactile learningを提案しました.この研究の新規性は,教師なしで潜在変数に触覚特性を表現したこと,及び,画像と触覚情報を含んだ新たなデータセットを作成したことです.今後の展望として,推定した触覚特性を元にロボットに把持や歩行などの行動をさせることです.

CuPy カーネル融合の拡張

Daisuke Nishino

2019-09-27 14:44:40

本記事は、2019年インターンシップとして勤務した徐 子健さんによる寄稿です。


2019年度夏季インターンのJoeです。この度インターンプロジェクトとしてCuPyのカーネル融合の拡張に取り組み、既存のカーネル融合の適用範囲を大幅に拡張しました。さらにその応用として、ResNet50のバッチ正規化においてCPU実行時間を30%ほど、GPU実行時間を(入力サイズに大きく依存しますがおおよそ)70%ほど削減することに成功しましたので、その取り組みをご紹介します。

背景

CuPyはNumPyと同じAPIを提供するPythonのライブラリで、CUDAを用いて演算を高速に行います。具体的には、行列・ベクトルの要素ごとの演算や、リダクションと呼ばれる、演算によって配列の次元が落ちる演算(たとえばcupy.sum)など、GPUが得意とする計算を高速に行うことができます。

さて、CuPyのGPU演算は強力ですが、CPUからGPUカーネルを呼び出す際には、GPU内で実際に行われる処理によらずおおよそ10 μsほどのオーバーヘッドがCPU側にかかってしまいます。cupy.addcupy.mulのような演算が呼ばれるたびにGPUカーネルを呼び出していては、無視できない量のオーバーヘッドが発生してしまいます。

そこで、いくつかの演算を融合したCUDAコードを実行時に動的に生成することにより、GPUカーネルの呼び出しを減らすことによる高速化が重要となります。この技術をカーネル融合といいます。詳しくは後述しますが、要素ごとの演算を組み合わせた関数やリダクション演算を一度まで含む関数に対するカーネル融合は現在のCuPyにもすでに実装されています。

https://docs-cupy.chainer.org/en/v6.4.0/reference/generated/cupy.fuse.html

カーネル融合で行っている処理を具体的に説明するために、以下のPythonで書かれた関数に配列(cupy.ndarray)を引数に与えて実行したときに、カーネル融合をしない場合とする場合に生成されるCUDAコードを比較してみます。


def f(x):
    return x + x * x

カーネル融合をしない場合

このとき掛け算と足し算の両方の呼び出しでCUDAコードが生成され、2度のカーネル呼び出しが発生します。

具体的には以下のようなコードが生成され、関数single_op_mulsingle_op_addがそれぞれ実行されます。


__device__ void mul_element(int &src1, int &src2, int &dst) {
    dst = src1 * src2;
}

__global__ void single_op_mul(Array& in, Array& out) {
    int a = in[tid], b;
    mul_element(a, a, b);
    out[tid] = b;
}

__device__ void add_element(int &src1, int &src2, int &dst) {
    dst = src1 + src2;
}

__global__ void single_op_add(Array& in1, Array& in2, Array& out) {
    int a = in1[tid], b = in2[tid], c;
    add_element(a, b, c);
    out[tid] = c;
}

カーネル融合をする場合

この場合、2つの演算は1つの関数にまとめられて、以下のように生成される関数fusedが呼ばれ、カーネル呼び出しは1回で済みます。


__device__ void add_element(int &src1, int &src2, int &dst);

__device __ void mul_element(int &src1, int &src2, int &dst);

__global__ void fused(Array& in, Array& out) {
    int a = x[tid], b, c;
    mul_element(a, a, b);
    add_element(a, b, c);
    out[tid] = c;
}

このとき、カーネル呼び出しの回数が1回に減るのでCPU時間が短縮されます。さらに、x[tid]部分はグローバルな配列にアクセスしていて、GPU側のボトルネックになりがちですが、処理をまとめることで、こうしたグローバル領域のアクセスの回数を減らすことができ、GPU側の高速化にも繋がります。

要素ごとの演算とリダクション演算のカーネル融合

既存のカーネル融合は要素ごとの演算だけではなく、一度までリダクションを含む関数ならば融合することができます。上述した例に示したような要素ごとの演算を組み合わせた関数に対するカーネル融合は比較的イメージしやすく、生成するCUDAコードもcupy.addcupy.mulに相当する演算をつなげるだけでいいので簡単ですが、要素ごとの演算とリダクション演算を融合しようとすると話は少しややこしくなります。要素ごとの演算のカーネル融合ではGPUの各スレッドが特定の位置の要素を独立に扱っていましたが、リダクション演算では、各スレッドは適切に同期されながらシェアードメモリに読み書きを行い、演算を処理します。

上の図は、既存のカーネル融合で、要素ごとの演算とリダクション演算からなる関数を融合した場合にGPUで行われる処理を表したものです。ここで、リダクション前の演算はすべてリダクションの入力と同じサイズ(正しくは、cupy.ndarrayshapeのこと。以下同様)をもち、 リダクション後の演算はすべてリダクションの出力と同じサイズをもちます。逆にこのような制約のもとで表せない関数には既存のカーネル融合を適用できません。

このような、リダクションを一度行う関数を融合することは、先程説明したような要素ごとの演算のみからなる関数を融合する場合よりは難しいですが、それでも元のリダクション演算の前後に、要素ごとの演算を織り込むだけで実現することができます。

課題

今回のインターンの課題は、カーネル融合で扱える関数の範囲を広げ、要素ごとの演算とリダクションからなる関数ならなんでも融合できるようにする、というものでした。実際既存のカーネル融合において、リダクションが一度までというのは大きな制約であり、例えば平均や分散の計算を伴うバッチ正規化の関数を融合することはできませんでした。バッチ正規化はResNet50などで何度も実行される関数であり、特にカーネル融合の効果が期待される処理でした。

取り組んだこと

リダクションを二度以上含む関数の融合は、一見リダクションを一度だけ含む関数の融合方法を簡単に拡張するだけで実現できるように思えますが、このニ者の間には大きな違いがあります。というのも、複数回リダクションが行われるとき、一度前のリダクションの結果を一時的にGPUのグローバル領域に格納する必要が生まれます。同じサイズの要素ごとの演算のみだと、各スレッドは配列の特定の要素を見続けるので、演算結果の変数をスレッドのローカル変数に保持しておくことができます(リダクション演算が一度だけの場合、出力用配列にそのまま保存するので問題ありません)。しかし、配列のサイズが演算間で変化するとき、スレッドが担当する要素がずれるため、一度結果をグローバル(スレッド間で共通してアクセスできる位置)に保存してやる必要があるのです。具体的には新たな空の配列をグローバル領域に確保しておき、それを使います。

カーネル融合の処理の流れ

具体的なアルゴリズムを説明する前に、カーネル融合の処理の流れについて整理しておきます。

各々の部分の詳細な説明は後述しますが、カーネル融合の処理は大まかに、解析パートと実行時パートに別れます。解析パートでは、CUDAコードを生成するために必要な情報を解析し、CUDAコードの最適化を行います。解析パートは同様な引数の組み合わせに対しては一度だけ実行されることを想定しています。一方、実行時パートは、毎回の関数呼び出しで実行されるパートのことを指します。ここでは、配列の次元圧縮とよばれる実行時最適化を行い、解析パートで得られた情報から実際にCUDAコードを生成し、コンパイルしてカーネルを呼び出します。何度も呼び出されることが想定される関数の場合、関数呼び出しあたりの平均的なCPUの処理時間は、この実行時パートの処理時間にかかっています。それでは、解析パートおよび実行時パートで行っていることを順に説明していきます。

解析パート

サイズの抽象化と制約生成

多段階のリダクションを実現する上で重要なことは、サイズが異なる演算が発生するたびに一時変数をグローバル領域に保存してやることでした。そうした一時変数のメモリを割り当ててやるためには、カーネル呼び出しの直前にサイズを決定してやる必要があります。なぜならば、同一の関数が異なるサイズの入力で繰り返し呼ばれる可能性があるからです。サイズが異なる入力が来るたびにPython関数を解析し直すのは非常に高コストなので、入力の配列のサイズが変わった場合にも同じコードを使えるように変数のサイズ情報を抽象化してを保存したいです。

サイズを抽象化して保存するためには、まず関数の引数で渡される配列のサイズを抽象化して保持します。たとえば、三次元配列xのサイズを(x0, x1, x2)のようにして保持します。これらの抽象化したサイズをもとに、演算を順に追っていき、一時変数の抽象的なサイズを決定します。こうした演算を追う過程で、演算がただしく成立するために必要な、サイズ間の制約が発生します。たとえば、(x0, x1, x2)のサイズの配列と、(y0, y1)のサイズの配列の要素ごとの演算を行うには、後者をブロードキャストする必要があり、このとき、x1, x2, y0およびy1がいずれも1でないとすると、y0 == x1かつy1 == x2がサイズ間の制約となります。これらの制約は関数の解析時に順次保存され、2度目以降の関数呼び出しの際に、与えられた引数のサイズが保存された制約を満たすならば、以前に解析した結果およびコードを使い回すことができます。

CUDAコードの生成

CUDAコードを生成する上での基本的なアイデアは、本稿の初めで説明した、要素ごとの演算のみからなる関数のカーネル融合とほとんど同じです。すなわち、関数内に登場するそれぞれの演算を呼び出し順に記録し、それをつなげて一つのCUDAコードにします。リダクション演算が続いたり、サイズが異なる要素ごとの演算が連続したりするときは、スレッド間で同期をとる必要が生まれますが、基本的にはそれぞれの演算を順につなげたコードを生成すればよいです。

CUDAコードの最適化

さて、ここまでの説明だけだと、カーネル融合が簡単なものに思えるかもしれません。実際、GPUの実行時間を考慮しないならば、演算ごとにサブルーチンを生成し、そのサブルーチンをすべて順につなげればひとつのCUDAコードが完成します。しかし、このままだと本当にGPUを呼び出すための10 μs程度のCPU側の高速化しかなされません。カーネル融合ではCPUのオーバーヘッドをへらすだけではなく、GPUコードの無駄な処理を省くことでGPU側の高速化をも期待することができます。

さて、各演算を順に結合しただけのCUDAコードは無駄な処理を多く含みます。たとえば直前の演算で結果をグローバルな配列に格納し、次の演算でまた同じ要素をグローバルな配列から読み出すのは明らかに無駄です。こうしたケースでは演算結果をスレッドごとのローカル変数に記録してやると大きな高速化に繋がります。

たとえば、愚直に生成したCUDAコード内で以下のような部分があったとします。


tmp[tid] = a;

// ここまで一つの演算に対応。変数aを出力として一時変数に格納
// ここから新しい演算が開始。変数aを新しい入力として一時変数から読み出す

int b = tmp[tid];

このとき、配列tmpが一時変数で、しかもここでしかアクセスされない変数であるならば、


int b = a;

と処理を短縮してやることができます。GPU演算で各スレッドが担当する演算は非常に軽量であることが多いため、このようにグローバル配列へのメモリアクセスを削減してやるだけでも大きな高速化に繋がります。

今回、要素ごとの演算間のみならず、リダクション演算が混じる場合にもこうしたグローバルなメモリアクセスを減らす最適化を行いました。他にもスレッド同期の削減など非常に多様な最適化を試行錯誤し、結果として、従来のカーネル融合を適用できる演算については、ほとんど劣ることがないレベルまでに最適化がなされています。また、高速化とは直接関係ないですが、一時変数の生存解析をすることにより、メモリを共有できる変数はメモリを共有することで、実行時の消費メモリを抑える最適化も実装されています。

実行時パート

配列の次元圧縮

詳細な説明は省きますが、多次元配列の要素にアクセスするとき、一次元配列の要素アクセスよりも時間がかかります。そこで、配列のデータ領域がメモリ上で連続していて低次元配列だとみなせるときに、要素アクセスをより単純に行うための実行時最適化を行います。完全なCUDAコードを生成するためにはこの最適化後の次元を知る必要があるため、完全なコードの生成およびコンパイルは実行時に行われます。CUDAコードのコンパイルはCPU時間に含まれますが、キャッシュされるので一般に高速であり、次元圧縮によるGPU実行時間の削減のほうが効果が大きいため、この方式を採用しています。

実験結果

ResNet50のバッチ正規化部分のコードを融合し、CPU時間とGPU時間を比較しました。実験を行った環境は以下のとおりです。CUDA: 10.1, GCC: 5.4.0 GPU: Tesla P100. また、ResNet50でバッチ正規化される配列のサイズは様々ですが、今回はその中の一つである(32,256,56,56)を採用しました。これは縦横56×56の画像を256チャネル分、32枚を正規化する処理に対応し、軸(0,2,3)について正規化をすることで、出力のサイズは(256,)になります。

比較対象は、カーネル融合をせずにそのまま呼び出した場合(naive)と、実際に採用されている実装である、要素ごとの演算部分だけを融合した実装(custom kernel)です。今回実装したカーネル融合(new fusion)はCPU時間、GPU時間の両方の削減に成功しました。

CPU時間は、実行時の配列のサイズに依存せずほぼ一定の割合短縮されました。また、GPU時間についても、従来のボトルネックであった、分散計算時の余分なメモリアクセスを潰すことができたため大幅に短縮されました。

まとめ

今回のインターンでは、既存のカーネル融合を拡張し、複数回のリダクション演算が含まれる場合にも対応し、無事高速化を達成できました。複数回のリダクション演算にも対応させたカーネル融合を実現する上での理論的な大枠はかなりシンプルで、一時変数に多くの情報(もっとも重要なものは抽象的なサイズ情報)を記録させながら演算をたどれば実現できるのですが、そうして生成されたコードは既存のカーネルで生成されるコードに比べ極めて冗長で、最適化を十分に施さない限り高速化が見込めない、という点が大変でした。アルゴリズムの大枠は序盤から見えていましたが、実際にベンチマークを更新したのはインターン終了直前という形になってしまいました。

アプリケーションに新しい機能を追加をする開発と違い、高速化を目指すための機能追加は、高速化を実現できて初めて世に広まるものなので、プロジェクト自体が成功するかどうかはインターン後半までかなり心配していましたが、無事に高速化を実現できてよかったです。

今回のインターンを通して、頼りになるメンター・副メンターとともにこのような挑戦的なプロジェクトに携われてよかったです。

ベイズ最適化を用いた高次元ブラックボックス最適化手法の検証

Yuhei Otomo

2019-09-27 14:12:18

本記事は、2019年インターンシップとして勤務した森 雄人さんによる寄稿です。


概要

2019年PFN夏季インターンに参加していた森 雄人です. 本インターンでは高次元空間中のベイズ最適化問題について, 実装・研究していました. 特にREMBO [1] [2]  やLINEBO [3] を用いた最適化を行うことで, どのようにアルゴリズムの振る舞いが異なるかを数値的に検証していました.

ブラックボックス最適化

本稿ではブラックボックス最適化問題, 特に最小化問題について考えます. 変数を\(\lambda\), 目的関数を\(L(\lambda)\)と書き, 探索空間を\(\Lambda \subset \mathbb{R}^{D}\)と書くことにします. ここで「ブラックボックス」とは, 最小化したい目的関数\(L(\lambda)\)にまつわる情報が手に入らないという想定を指します. すなわち, 自分である入力\(\lambda\)を選び, その出力\(L(\lambda)\)を得ることはできるけれども, \(L(\lambda)\)の勾配\(\nabla L(\lambda)\)などの情報は手に入れることができない, という最小化問題を扱います. このような状況では勾配法に基づく最適化アルゴリズムを用いることができないため, 異なる手法を適用する必要があります.

ブラックボックス最適化が必要となる代表的なシーンとしては「ハイパーパラメータ最適化」があります. 例えばSupport Vector Machine (SVM)の訓練時において, validationデータに対する損失を, SVMの最適化問題に現れる正則化項係数\(C\)や, カーネルのスケールパラメータ\(\gamma\)の関数として捉えてみましょう. するとこれはvalidationに対する損失を目的関数とした\(C, \gamma\)についてのブラックボックス最適化問題になります. 通常ハイパーパラメータ探索はランダムサーチやグリッドサーチが用いられますが, 近年次に示すベイズ最適化などのアプローチが注目されてきています.

ベイズ最適化 (Bayesian Optimization)

ベイズ最適化とは不確かさを用いながら次に探索すべき点を決定するブラックボックス最適化アルゴリズムです. 具体的なアルゴリズムとしては次のようになります.

キーとなるステップは非常に単純です.

  1. 今まで調べた点を用いて真の関数\(L(\lambda)\)を近似する関数\(a(\lambda)\)を作る
  2. \(a(\lambda)\)を最小化する点\(\hat{\lambda}\)を求める
  3. \(L(\hat{\lambda})\)を求め, 調べた点のリストに追加する

真の関数\(L(\lambda)\)を近似した関数\(a(\lambda)\)を獲得関数 (acquisition function) と言います. この獲得関数の構成に確率過程, 特にガウス過程を用いる手法がベイズ最適化と呼ばれます.

次に示す図は\(a(\lambda)\)としてLower Confidence Bound (LCB) を用いた図です. 今までチェックした点から, 探索できていない領域の不確かさをも含めて関数を近似し, 次に探索すべき点を探す流れを表しています.

ベイズ最適化は一般に, 20次元以上ほどの高次元空間では局所解に陥ってしまったり, 獲得関数の最小化がうまくいかないなどの理由で, 度々うまく動かないことがあります. そこで高次元空間中のベイズ最適化問題が研究されてきています.

REMBO

Random EMbedding Bayesian Optimization (REMBO) [1] [2] は, ランダム行列を用いて低次元空間を高次元空間に埋め込むことで, 高次元空間を陽に扱わずにベイズ最適化を行う手法です. この手法は真の関数\(L(\lambda)\)に
$$ L(\lambda_{\top} \oplus \lambda_{\perp}) = L(\lambda_{\top} \oplus 0) $$
という「縮退した線形空間があって, ある方向に動かしても\(L(\lambda)\)の値が変わらない」性質がある場合に効果を発揮します. これは\(\lambda\)の中に冗長なパラメータがある場合や, \(L(\lambda)\)に寄与しないノイズのような次元があるときに対応しています.

アルゴリズムとしては直接, 高次元空間\(\Lambda\)を扱うのではなく, 低次元空間\(Z \subset \mathbb{R}^{d}\)上でガウス過程を構成し, この空間内で最適化を行います. このとき\(z \in Z\)に対し, 各成分が独立な正規分布\(\mathcal{N}(0, 1)\)に従うランダム行列\(A \in \mathbb{R}^{D \times d}\)を用いて\(L(Az)\)を求めることで真の関数の評価を得ます. なお, 埋め込んだ\(\lambda = Az\)が現在考えている探索空間\(\Lambda\)の外に出てしまっている場合は探索空間上に射影を行います.

LINEBO

Line Bayesian Optimization (LINEBO) [3] は獲得関数の最小化を1次元空間に制限した上で行う手法です. 探索空間を1次元空間に制限する方法はいくつか考えられますが, \(\lambda\)を座標降下させる方法, または\(– \nabla a(\lambda)\)の方向に下る方法が比較的優位であることが数値的に示されています.

 

実験・観察

本稿ではテスト関数\(L(\lambda)\)としてSTYBLINSKI-TANG関数を用います. これはブラックボックス最適化のベンチマークとして使われる標準的な関数の一つで, 入力の次元数\(D\)を柔軟に設定することができます. 今回はベイズ最適化にとって比較的高次元とされる次元数である25に設定し, 探索空間\(\Lambda\)は通常用いられる\([-5.0, 5.0]^{25}\)としています.

実装としてはGPyTorch [4] をベースにしたベイズ最適化ライブラリBoTorchを用いています. GPyTorch・BoTorchを用いることの利点として, 従来ベイズ最適化の計算量のボトルネックであった「ガウス過程の予測」の段階における高速化が挙げられます.

さて, 次に示すのはアルゴリズムごとに各ステップにおける評価値\(L(\lambda)\)をプロットした図です.

 

ここで実験設定の詳細についてさらに述べておきます. Basic-BOとは獲得関数の最大化の際に特に何もせず, そのまま25次元空間上を探索するアルゴリズムを指します. またREMBOにおいて, 低次元空間の次元数は10次元, 探索空間\(Z\)は\([-1.0, 1.0]^{10}\)に設定しています. LINEBOでは降下方向として各次元の軸に沿った方向, すなわち座標降下法を用いています. 降下する軸の選び方は25次元の中から一様ランダムに選んでいます.  global optとは25次元STYBLINSKI-TANG関数の大域的最適解\(\lambda^{*}\)における\(L(\lambda^{*})\)の値を示しています.

また, アルゴリズムに依らずカーネル関数はRBFカーネル, 獲得関数はLCB, 初期点の数は200で統一しています.  REMBOのみ探索空間が低次元空間であるため, 初期点は低次元探索空間\(Z\)上から, Basic-BOとLINEBOは\(\Lambda\)から一様にサンプリングしてきた共通のものを使用しています.

実験結果から得られる観察として, まずどのアルゴリズムも大域的な最適解に収束できていない様子が見られます. 各アルゴリズムごとに見ると, Basic-BOはステップ数が増え, 探索点が増えていった場合にほとんど同じ評価値を取り続けており, 探索が十分に行われていない様子が見られます. 一方でREMBO, LINEBOはステップ数が増えた場合にも探索が行われている様子が確認できますが, 評価値の大きな改善には至っていないことがわかります. しかし, REMBO, LINEBOはBasic-BOに比べ少ないステップ数でより小さい評価値を得ていることがわかります.

結論

本稿では高次元空間中のベイズ最適化手法の収束性について数値的に検証しました. 結果として, どのアルゴリズムもテスト関数に対して大域的な解を得ることはできていなかったものの, REMBO, LINEBOは高次元空間中でも探索する様子が見られ, 標準的なベイズ最適化よりも速い収束性が観察されました.

一点注意すべき点としてベイズ最適化はフレームワークとして柔軟であるが故に, カスタマイズできる点が複数あることが挙げられます. 例えば, 「どのような獲得関数を使うか」, 「カーネル関数はどのようなものを用いるか」, 「初期点はどれぐらいにするか」などといった点です. そのため, 本稿での実験結果がそのままベイズ最適化の限界を表している訳ではないことに留意すべきです.

実際の業務ではテスト関数に留まらず, より複雑な関数に対してベイズ最適化を適用し, どのような結果が得られるか, どのような発展が考えられるかを試行していました. 今回, このような大変刺激的なテーマで研究する機会を頂いたことに感謝致します.

参考文献

[1] Wang, Ziyu, et al. “Bayesian optimization in high dimensions via random embeddings.” Twenty-Third International Joint Conference on Artificial Intelligence. 2013.

[2] Wang, Ziyu, et al. “Bayesian optimization in a billion dimensions via random embeddings.” Journal of Artificial Intelligence Research 55 (2016): 361-387.

[3] Kirschner, Johannes, et al. “Adaptive and Safe Bayesian Optimization in High Dimensions via One-Dimensional Subspaces.” arXiv preprint arXiv:1902.03229 (2019).

[4] Gardner, Jacob, et al. “GPyTorch: Blackbox matrix-matrix gaussian process inference with gpu acceleration.” Advances in Neural Information Processing Systems. 2018.

PFN Dayの紹介

海野 裕也
リサーチャー

2019-09-27 12:31:38

5月から執行役員になった海野です。Preferred Networksでは昨年の7月より、PFNDayという全社員参加の社内カンファレンスを3〜4ヶ月に1回開催しており、私はその運営をやっております。

続きを読む »

KDD Cup 2019 AutoML Trackで5位に入賞しました。

Masashi Yoshikawa

2019-09-18 11:19:56

エンジニアの吉川です。

先日8/3~8/7にデータサイエンス応用の国際会議KDD 2019が開催され、弊社からも5人のメンバーが参加しました。
このKDD 2019の中でKDD Cup 2019というコンペティションが開かれ、その中のAutoML TrackにPFNのチーム(吉川真史、太田健)も参加し、5位に入賞しましたので、ここで報告したいと思います。

 

KDD Cup 2019 AutoML Trackについて

KDD Cup は KDDに付随して毎年開かれるデータサイエンスのコンペティションで、最初のコンペが開催されてから20年以上がたちます。昨年までは、通常のデータサイエンスのコンペティション同様に、データが与えられて、参加者が自分の環境で、データを分析し、何らかの予測を行い、その精度を競うというコンペでした。今年からは、それに加え、AutoML TrackとHumanity RL Trackが新設されました。また、AutoML TrackはKDD Cupの一つの部門という位置付けであると同時に、AutoML Challengeという2014年から開催されているコンペティションも兼ねています。

AutoMLはAutomated Machine Learningの略で、機械学習の一部、あるいは全体のプロセスを自動化することを言います。コストを削減したり、機械学習導入の障壁を下げることが期待されていて、KaggleでもAutoMLのベンチマークとしてコンペティションのタスクを提供するなど、最近注目されています。

 

問題設定

今回のコンペティションでは、参加者がAutoMLの処理を行うコードを提出し、それをコンペが用意した環境で動かし、その性能を競います。

問題設定は、複数テーブルデータに対する2値分類のタスクです。テーブルデータとは、CSVファイル等の形式で表現されているデータ形式で、行列と似たような形で値が格納されています。このテーブルデータが複数あり、データセットに対して1つのメインテーブルが用意されています。このコンペに提出するコードで、メインテーブルのそれぞれの行に対して、何らかの事象が1か0かを確率として予測します。

上の例では、メインテーブルのそれぞれの列には、instance_id, user_id等が割り当てられているのですが、それぞれデータの型を持っています。

  • numerical: 連続値
  • categorical: 離散値(上の例だとidや、gender等)
  • time: 時間
  • multi categorical: 任意の長さのcategoricalデータの列(例えば、自然言語で書かれた文で単語のIDを並べたものなど)

また、計算リソースに対する制約もあり、

  • 時間制限
  • CPUの数
  • メモリの大きさ

それぞれに対して、うまく対処する必要がありました。

 

今回のコンペの傾向

今回のコンペでは、161チームが参加しました。順位変動が大きいコンペティションになっていたと思います。データセットとして、公開されているpublicのデータセットと、公開されていないprivateのデータセットが用意されました。開催期間中はpublicの順位が表示されているのですが、最終的な結果はprivateで判断されます。publicのみで高い性能を出すコードを提出した場合、順位が落ちてしまうということが起こります。

また、エラーに関してシビアなコンペになりました。最終的な評価の時にprivateデータを使うため、仮にpublicでエラーなく動いたとしても、privateでエラーが出てしまった場合に、評価ができません。このコンペでは、1回エラーが出た場合に再提出が許されましたが、2回目のエラーは許されないというルールでした。実際我々のチームでも1回目はTimeout Errorが出てしまいました。

これらのことがあり、publicで入賞圏内にいた10チームのうち5チームのみが最終的に入賞することになりました。

入賞したチームのほとんどが、前処理 -> 特徴量エンジニアリング -> ハイパーパラメーター調整 -> モデリングと言うパイプラインで行っていて、そのそれぞれを工夫するということをしていました。 機械学習モデルとしては全入賞チームがLightGBMを使っていました。

 

我々の開発方法

まず、開発・検証環境を整えました。ただし、基本的には性能検証のコードや環境のDocker imageは運営で用意されていましたので、それをほとんど使いました。データに関しては、publicのデータセットについてはラベルが用意されていなかったので、trainデータを時間で分割するという方法で、検証用のデータを用意しました。これにより提出することなしに、自分の環境で検証が回せるようになりました。

 

今回、検証の時に課題に感じたのが、複数データセットに対して、いかに汎用性の確度の大きく、高速に検証を回すようにできるかということです。全てのデータセットに対して、検証を行うと、時間がかかってしまいます。かと言って一つのデータセットだけを回すと汎用性の低いものができてしまうと思います。自分は今回は、複数データセットをその都度選んで検証するという方法をとりましたが、やっていくうちに、あるデータセットだけに偏って検証してしまうということがあり、最終的なモデルの汎化性能に影響が出てしまった可能性があります。

 

我々のソリューション

実際に発表に使ったソリューションのポスターが以下になります。

一番工夫したところは、特徴量エンジニアリングをするところです。特徴量エンジニアリングは、機械学習が予測しやすいように、特徴量を作ることを言います。自動特徴量エンジニアリングの研究というのはいくつかなされていて(Deep Feature Synthesis[1], One Button Machine[2])、ルールベースに特徴量を作ってしまうという方法がベースになっています。

我々の手法でも、同様のアプローチをとりましたが、ルールベースで全ての特徴量を合成してしまうと、とてもリソースを消費してしまったり過学習の要因になり得ます。そこで、事前に特徴量を選ぶということを行いました。

  1. 実際に特徴量自体を計算せずに、どういう特徴量がありうるかを列挙する
  2. それぞれの特徴量のメタ特徴量(どういう特徴量かということをベクトルとして表現したもの)を計算する。
  3. そのメタ特徴量をある関数に通すことで優先度を計算する。

これをすることで、重要な順番に特徴量を合成することができ、メモリや時間を使いすぎていたら途中でやめることができます。実際これによって順位が大幅に上がりました。

ここで優先度を計算する関数ですが、これをメタ学習により作りました。

  1. 他のデータを使って特徴量を全てあらかじめ計算しておき、Permutation Importance(特徴量の重要度を計算する方法の一つ)を計算する。
  2. それをメタ特徴量から線形回帰する。

このようなメタ学習をすることにより、他のデータセットで得られた知見を適用することで良い優先度づけができることを期待しました。

またハイパーパラメーター最適化では、ハイパーパラメーター最適化ツールであるOptunaを使用しました。ハイパーパラメーター最適化では、ハイパーパラメータを変えて実際に何回か学習を回します。そのため、時間がかかってしまい、いかにそれを短くするかというところが重要です。今回は、Pruning(枝刈り)というテクニックを効率化するために使いました。Successive Halving AlgorithmというPruningのアルゴリズムがOptunaに実装されていて、それを使用しました。

 

1stソリューション

今回のコンペでは、1位のチーム(DeepSmart)が2位以下に大きな差をつけていました。データセットによっては、他のチームが0.7や0.8というAUCの中、AUC=0.99というスコアを出していました。1位のチームも大枠の前処理 -> 特徴量エンジニアリング -> ハイパーパラメーター調整 -> モデリングというパイプラインは同じであり、KDD 2019での発表を聞いても、どこでそこまで大きな差がついたかわかりませんでした。そこで、実際にpublicのデータで調査を行いました。

 

結論から言うと、McCatRankという特徴量が決定打でした。1位のソリューションから、そのまま動かした場合と、McCatRankに関する部分を除いで動かした場合の結果が以下のようになります。特にデータセットCとデータセットEで差が出ていることがわかります。

このMcCatRankという特徴量は、下の図のように、Multi CategoricalのデータとCategoricalのデータを取ってきて、Multi Categoricalの中でCategoricalがなかった場合に0を、あった場合に何番目にあるかと言う値を特徴量としたものです。

試しに、データセットEから、あるMulti CategoricalデータとあるCategoricalデータを取ってきて、McCatRankの特徴量を作りました。このデータセットの場合では、特にMcCatRankが0かどうか(つまりCategoricalの値がMulti Categoricalの中にあるかどうか)が、ラベルと相関があって、以下の表にような集計が得られました。実際にこの特徴量単体でAUC=0.951となり、McCatRankを使わずに学習した場合の性能を上回っていました。

 

また、このチームのコードでは、ハイパーパラメーター最適化では、hyperopt,Optunaなどのツールを使っておらず、データサイズ、特徴量の数などから、ルールベースに決めたり、全探索的に探索したりして、そのルールを試行錯誤していたようでした。実際に今回の問題設定では、ブラックボックス最適化アルゴリズムをそのまま適用するよりも、人間の経験に基づいて最適化の方法を決めた方がよかったのかもしれません。

 

最後に

今回のコンペでは、AutoMLに関する知見を得ることができ、とても有意義なものになりました。他チームのソリューションからは、自分が思いついていなかったアプローチが多くあり、学ぶことがありました。

PFNではAutoMLに関して社会実装に向けた、Optunaを中心とした技術開発を進めていきたいと考えています。

 

文献

[1] Kanter, James Max, and Kalyan Veeramachaneni. “Deep feature synthesis: Towards automating data science endeavors.” 2015 IEEE International Conference on Data Science and Advanced Analytics (DSAA). IEEE, 2015.

[2] Lam, Hoang Thanh, et al. “One button machine for automating feature engineering in relational databases.” arXiv preprint arXiv:1706.00327 (2017).