視覚からの触覚特性の推定 (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).

KDD 2019 で発表しました

木下 僚

2019-09-09 17:32:48

8月上旬、KDD 2019 という年次国際学術会議が開催されました。KDD とは「知識発見とデータマイニング」(Knowledge Discovery and Data Mining) の略であり、いわゆる「データサイエンス」分野におけるトップ会議に位置づけられる学会です。

エンジニアの木下です。我々のチームでは、さまざまな産業分野の困難な課題解決のために機械学習技術を応用・実践するための研究開発や、そのような研究開発プロセスを効率化するための技術開発に取り組んでいます。この過程で我々 PFN も、現実のデータと大規模計算機資源 MN-2 を活用した「データサイエンス」に日々取り組んでいます。

このたび PFN は、KDD 2019 にリサーチャー・エンジニア総勢5名で参加し、3件の発表を行いました。本記事では KDD 参加レポートとして、PFN からの発表を含め、会議の様子をお伝えします。

KDD 2019 closing session スライド:筆者撮影

KDD 2019 closing session スライド:筆者撮影

KDD 2019 会議概要

KDD 2019 は8月4日から8日の5日間にかけ、米国アラスカ州アンカレッジにて開催されました。昨年と同様に、初日は「Tutorial Day」2日目は「Workshop Day」3〜5日目が本会議という日程が組まれました。会場はアンカレッジ市街地にある Dena’ina Center(基調講演・企業展・チュートリアル会場)と Egan Center(セッション会場)の2箇所に設けられ、世界各国から 3000 人を超える参加者が集いました。各日とも朝8時から発表が始まり、初日と最終日は夕方5時ごろまで、それ以外の3日間は夜 10 時ごろまで、みっちりと会議や交流が行われました。

会議の予稿やデモ動画はすべて KDD ウェブサイト上で公開されており、誰でも読むことができます。パンフレットも公開されており、本会議に採択された論文数は 321 件、採択率は 17.8% であったと公表されています。本会議は研究の要素が強い Research Track と、現実世界への応用・実践事例紹介の色彩が強い Applied Data Science Track の大きく2部からなり、特に後者は投稿数が昨年比約 40% 増だったそうです。

PFN の発表

今回の KDD では PFN からつぎの3件の発表を行いました。発表はいずれも日程3日目(8月6日)に行われました。

Applied Data Science Track では、タイトルの通りそれぞれ ChainerOptuna の論文発表を行いました。ポスター発表には多くの方にお越しいただき、両フレームワークに対する関心の高さを感じました。

齋藤による Chainer 発表:筆者撮影

齋藤による Chainer 発表:筆者撮影

佐野による Optuna 発表:秋葉撮影

佐野による Optuna 発表:秋葉撮影

齋藤による Chainer 発表:筆者撮影

齋藤による Chainer 発表:筆者撮影

佐野・秋葉による Optuna 発表:筆者撮影

佐野・秋葉による Optuna 発表:筆者撮影

もう1件の発表は KDD Cup での入賞発表です。KDD Cup はデータサイエンス技術を競う世界トップクラスの大会であり、毎年の KDD 本会議に合わせて開催されています。KDD Cup としては今回初めて設定された AutoML(自動機械学習)トラックにおいて、PFN から参加したチームが第5位に入賞しました。KDD Cup Workshop では、この大会で今回 PFN チームが用いた手法についての口頭発表とポスター発表を行いました。なお、この発表については、入賞者本人によるブログ記事公開を後日予定しております。

賞状を持つ吉川:秋葉撮影

賞状を持つ吉川:秋葉撮影

吉川による受賞発表:筆者撮影

吉川による受賞発表:筆者撮影

会場の雰囲気

ここからは KDD 2019 会場の様子をお伝えします。

舞台裏

冒頭でも述べたとおり、今回の KDD には世界各国から主催者発表で 3000 人を超える参加者が集まりました。アンカレッジの人口が約 30 万人だそうですので、その 1% に相当する人が殺到したことになります。学会が提供した宿泊施設ではオーバーブッキングが相次ぎ、予約したホテルに宿泊できない参加者が続発してしまいました。PFN でも2人がこのトラブルに巻き込まれてしまいました。救済策としてアラスカ大学アンカレッジ校の大学寮が当日提供されましたが、そちらでも大きな混乱があったようです。

深刻な宿不足問題はありましたが、KDD の会議は予定通り進行しました。セッション会場の Egan Center は参加者数に対してあまりにも部屋が狭く、椅子に座りきれず立ち見が続出したり、部屋から人が溢れたりする光景が目につきました。たとえばこちらは AutoML Workshop が行われた会議室ですが、参加者が廊下まで溢れてしまっていました。このワークショップに参加した PFN メンバーによれば、室内もやや酸欠状態だったとのことです。今回の KDD は何かと苦労の多い会議になってしまいました。

AutoML Workshop の外側:筆者撮影

AutoML Workshop の外側:筆者撮影

ワークショップ

KDD 2019 では 34 のワークショップが開催されました。少しピックアップして紹介します。ワークショップの発表内容も、多くはそれぞれのウェブサイトで公開されています。

上述の AutoML Workshop は機械学習の自動化に関するワークショップです。機械学習の研究開発は多くの試行錯誤を伴いますが、この作業を自動化・効率化する動きが近年活発になっています。PFN でもハイパーパラメータ最適化フレームワーク Optuna の開発などを進めています。こちらのワークショップには多くの参加者が集まっており、関心の高さが伺えました。

IADSS Workshop は「データサイエンス」という仕事そのものについてのワークショップです。「データサイエンティスト」の仕事は増えていますが、その内容やスキルセットは会社・個人によって千差万別です。これがどのような仕事であり、どのような能力を必要とし、どのように評価されるかについては、まだはっきりとした共通理解がありません。このことは「データサイエンス」(あるいは「AI」)プロジェクトの失敗を増やし、「データサイエンティスト」の教育・採用・人事評価を難しくする要因になっています。会議では必要なスキルセットやプロジェクトの進め方についての提案や調査などの発表・議論が行われました。このワークショップは人事・教育担当者向けの色彩が強いものですが、エンジニアの観点からも、どのようなスキルセットを自分が身につけていくべきかを考える参考になるものだと思いました。ワークショップでの発表資料がいくつか公開されていますので、ご興味のある方はご覧ください。

本会議

基調講演2件のほか、300 件を超える口頭発表・ポスター発表が会議を通じて行われました。KDD は技術の実応用を重視する学会ということもあり、現実の「データサイエンス」に関わる問題意識に根ざした発表が今回も多く行われました。予稿はすべて公開されています

米デューク大学の Cynthia Rudin 教授による基調講演のトピックは主にモデル選択でした。現実世界を説明する機械学習のモデルは、識別や予測の精度の高さだけではなく、モデルの簡潔さ・わかりやすさもその良し悪しを評価する重要な要素です。講演の前半では新しい指標を用いてモデル選択を行う研究が紹介されました。スクリーンに「Rashomon」と映し出されたとき、初めは海外の研究者の名前か何かかと思ってしまいました。この研究では「Rashomon effect」すなわち羅生門効果の考え方を用いています。羅生門効果は映画『羅生門』にちなんだ専門用語であり、同じ現象について異なる説明が多くなされることを表しています。機械学習の文脈において、同じタスクに対して自分と同程度以上の精度を達成できるモデルがどれだけ存在するかを見積もるような値である「Rashomon ratio」なる指標を定義します。モデルの複雑さ・説明力によって経験損失と Rashomon ratio が変化し、その関係に基づいてモデル選択を行うという研究が紹介されました。

異なる分野で考えられてきたアイディアや技術を新しい問題に持ち込んで解決するということは、現実の問題解決の現場ではよく行われています。要素技術そのものはすでに知られたものであっても、その適用・応用に新しさや面白さ・インパクトがあると、KDD での議論の対象になります。今回の本会議セッションでは、Web 広告の入札に PID 制御を応用する協調フィルタリングを AutoML のモデル選択に応用する逆強化学習を異常検知に応用するなどの事例が発表されていました。Web マーケティング系のアプリケーションに関する別の発表では、発表者・参加者に制御理論に関する知識が不足したために質疑が成立しない場面もありました。まさに Learn or Die といったところで、他分野・異分野への広い興味や知識が現実の「データサイエンス」を支えています。

個人的に好きだった発表は配車サービスのマッチングをフェアにする研究です。配車サービスは「乗客」と「運転手」の2つの集団間でのマッチングを解き続けるものです。一般的には二部グラフマッチングの問題といえますが、保育園や婚活などのマッチングとは異なり、比較的短い時間に同じものが繰り返しマッチする点で配車サービスはやや特殊なケースとなっています。乗客の利便性を重視して待ち時間の短い運転手と常にマッチさせると、うまく稼げる運転手と稼げない運転手が出てくるという運転手間格差の問題が生じます。一方、収入の低い運転手から優先的にマッチするような「平等性」を導入すると、乗客にとっては待ち時間の増大につながります。部分最適ではなく全体最適を目指し、この研究では乗客と運転手それぞれの観点での不平等さ・効用を含めた形で最適化問題を設計することで、乗客の待ち時間の悪化を抑えながらも収入の不平等を緩和するマッチング手法を提案しました。真に実現すべき「全体最適」とは何か、リアルタイムに動作させるにはどうするか、などの課題は残っていますが、複雑な課題をシンプルな発想で解こうとする、良い発表だと思いました。

企業展

Dena’ina Center の1階が昼食会場を兼ねた展示会場となっており、多くの企業がブースを出していました。しかし今回の KDD の企業展示は、個人的な感想ですが、昨年に比べると規模が小さくなったように感じました。出展数は変わらないかもしれませんが、一つ一つのブースが小さめに感じました。また今回の KDD は Google がスポンサーに入っておらず、Google ブースがなかったことも意外に感じました。

コーヒー休憩の際にも展示場やロビーで軽食が提供されました。アラスカ名物スモークサーモンも出ていました。塩気が強めでしたがおいしかったです。

ケータリング:筆者撮影

ケータリング:筆者撮影

アンカレッジの雰囲気

今回の KDD で初めてアラスカに行きました。行く前はどんなところかと不安でしたが、いざ行ってみると、夏のアンカレッジは非常によい都市でした!

北緯60度に位置するアンカレッジでの夏は日がたいへん長く、開催当時の日没時刻は午後 10 時半ごろでした。KDD 2019 は毎日夜まで行われましたが、午後8時ごろのポスターセッションは「西日が差す」中で行われました。ポスターセッションを終えて外に出ても、この写真のような青空で、まだまだ夕方前といった感覚でした。夏は遅い時間でも明るく、歩きやすい街だと感じました。会議中はほとんど晴れて、朝晩はやや涼しく、日中も T シャツ1枚で過ごして暑くない程度の心地よい空気でした。

午後8時すぎ Dena’ina Center 前にて:筆者撮影

午後8時すぎ Dena’ina Center 前にて:筆者撮影

アンカレッジへの出張旅行には、日本から遠い(アメリカ本土を経由するため片道 20 時間以上かかる)とか物価(特に宿泊費)が高いとか、宿の確保でトラブルがあったなどといった難点もありましたが、個人的にはこれまで行った海外の都市の中でいちばん居心地の良いところでした。

おわりに

機械学習技術を現実に役立てるために「データサイエンス」は様々な場面で活躍しており、その事例や最新技術が KDD で多く報告されています。会議での発表内容は多くが学会の Web サイト上で公開されていますので、技術的な内容はそちらである程度追いかけることができます。本記事では、そこにはない現地の空気感や個人的な印象を中心に KDD 2019 をレポートしました。世界的な技術動向をにらみながら、我々 PFN も、機械学習技術を応用・実践して現実の問題を解決するための研究開発に引き続き取り組んでまいります。

化学反応におけるDeep learningの適用

Kosuke Nakago

2019-09-06 10:57:59

近年様々な分野に対してDeep learningの応用が研究されてきています。

化学の分野でも物性値の予測モデルや、化合物の生成モデルの研究などが盛んになってきています。最近では、有機化合物の合成を行う際に必要な化学反応の予測をDeep learningで行うという試みが行われてきているのでその先行研究サーベイをしました。

サーベイ資料はこちらのSlideshareにアップロードしています。

合成経路探索 -論文まとめ- (PFN中郷孝祐) from Preferred Networks

 

問題設定:反応予測および逆合成経路探索

化学反応で、反応物 (reactant) AとBを触媒 (reagent) Cの下で反応させたときに 生成物 (product) D ができたようなプロセスは Reaction SMILES を用いると “A.B.C>>D” というように表すことができます。

 

 

ここで、 AとBとC から何ができるか? (答えはD)を予測する問題を順方向の反応予測問題と呼び、Dを作るためには何を用いればよいか? (答えはA, B, C)を予測する問題を逆方向と呼ぶことにします。

一般的に、A, B, Cを与えた時に順方向でどういった反応が起こるかは限定されていますが、ある生成物 Dを作る方法は複数可能性がある場合があり、逆方向の解析の方が難しい問題です。

例えば創薬など、目的の性質を持つある有機化合物が先に決まっていて、それを工業的に合成するためにどういった反応物を用いればいいか知りたい場合は、逆合成解析 (retrosynthetic analysis)・逆合成経路探索が必要となります。

機械学習で予測モデルを作る際、順方向の予測問題は実際にデータセットにある反応で生成物が当てられたかどうかの精度で評価することができますが、逆方向の予測問題はデータセットにはないが現実で起こりうる反応物の組み合わせに分解することもできるため評価も難しいです。今回読んだ論文では、既に知られている化合物の合成プロセスを見つけることができたかどうか?で、逆合成経路の性能評価を行っていました。

 

研究動向

従来は、機械学習を用いるのではなく、反応パターンを事前に人が定義しておいて、そのパターンに当てはまるかどうかをルールベースで計算することで反応の予測計算をしていました。しかし、この方法では以下の問題があります

・反応パターンとして事前定義したパターンの適用しかできず、複数パターンにマッチした場合の優先度決めが難しい(精度面)

・パターンのマッチにはグラフのサブグラフマッチングが必要で計算が重い(速度面)

 

そこでデータドリブンで反応を扱う取り組み、特に深層学習を用いるアプローチが考えられ始めました。

2016年頃は合成ルール等をある程度制限し、限定された合成ルールに対して機械学習を適用するといったアプローチが主でした。(上図、一番左側)

これまではそもそも研究用途に使えるデータが整備されておらず、一部の研究機関のみがClosedで研究しているような状況でしたが、最近 アメリカのパテントから化学反応を集めて整備した、USPTOデータセットが公開され、順方向の反応予測に適用されました。

データセットが公開された2017年頃から一気に、Deep learningの適用により順方向の予測精度をあげる研究が盛んになってきました。(上図、真ん中・右側)

現在、2通りのアプローチが競争している状況です。

1.分子をグラフとみなして Graph Convolutionモデルを用いるアプローチ

2.分子をSMILES記法の文字列で表現してNLPの分野で発展した自然言語処理モデル(seq2seq、Transformer)を用いるアプローチ

(それぞれ手法の詳細は割愛します、SlideShare でご覧ください。)

 

どちらのアプローチも高精度で反応を予測できるようになってきており、すでに化学研究者よりもきちんと反応を予測できるという報告もあります (下図は Jin et al. より)

 

現時点では MolecularTransformer という自然言語処理側のモデルがSoTAを達成しているようです。IBM RXNとしてWebサービスでも公開されています。

上記のように順方向の反応予測は精度が向上してきており、今後の課題・発展として逆方向経路探索への適用や合成可能性を考慮した生成モデルの研究などがあげられます。

 

さいごに

今回紹介したような領域では、反応・合成の知識(化学側)と研究スピードの速いDeep learningの最先端の知識(コンピュータ側)双方を深く理解する必要があり、画像などの領域と比べるとまだ参入者がそれほど多くない印象です。

しかし、徐々に論文や公開実装も出てきており、このような領域でもDeep learningの技術優位性がでるかどうかの研究はこれからどんどん盛んになっていくのではないかと感じています。

再計算でニューラルネット学習時のメモリ消費を減らす

楠本充
エンジニア

2019-09-04 11:40:25

エンジニアの楠本です。深層学習で再計算と呼ばれる手法を使って学習時のメモリ消費を削減する研究や実装に取り組んでいるのでその紹介をしたいと思います。

背景

大規模なニューラルネットの学習ではしばしば誤差逆伝播(以下同様)で GPU のメモリ不足に陥ることがあります。

通常、誤差逆伝播ではパラメータについての勾配を求める際に必要な順伝播の計算結果を (途中の計算結果も含めて) すべて覚えた状態で勾配計算を行います。

一方で、例えばコンピュータビジョンの重要なタスクであるセグメンテーションや物体検出では入力画像として高解像度のものがしばしば扱われます。モデルについても高精度を達成するために複雑なネットワーク設計、すなわち層が深くまた中間表現のチャンネル数の多いネットワークが使われることが少なくありません。

このように入力やモデルが巨大である場合には記憶しておくべき途中の計算結果全体が巨大になり、学習中のメモリ不足に繋がります。

GPU のメモリサイズはハードウェアの進歩で大きくなってはいるものの、大規模な学習には足りないことがあります。現状で商用販売されているGPUのメモリは最もハイエンドな Tesla V100でも最大 32 GB であり、大規模な学習ではメモリ不足を回避するためにバッチサイズをかなり小さい値にしなければいけないことがあります。バッチサイズを小さくすることは Batch Normalization で使われる統計情報推定を不正確にし、モデルの精度低下につながることが検出等のタスクで知られています[1]。

メモリ不足は深層学習の根幹的な問題であるため様々な解決方法が試されています。例えば半精度浮動小数点数 (FP16) やネットワークのサイズ削減などはその一例でしょう。しかしこれらは本来学習したいモデルに直接変更を加えることになるため、予測精度を悪化させることに繋がりえます。これから紹介する再計算と呼ばれる手法を使うとモデルの予測精度を変えることなくメモリを削減することができます。この場合、精度ではなく、学習時の計算時間が増えることを引き換えにします。

逆誤差伝播法の復習

ここで少し順番が前後しますが、ニューラルネットの学習方法である誤差逆伝播法について今一度復習します。

ニューラルネットワークは変数と計算の順序関係を示す計算グラフによって表現できます。この計算グラフをどう表現するかはいくつか流儀がありますが、ここでは計算グラフは変数を頂点とするグラフとします。これには入力変数、中間変数、出力変数を含みます。変数から変数の間には直接的な依存関係がある場合に枝が生えているものとします。

誤差逆伝播法は入力変数(モデルパラメータを含む)に対してその勾配を求めるための方法です。誤差逆伝播法の計算は多変数関数のチェインルールに基づいて計算されます。一般に勾配計算ではネットワークの出力を y として、それぞれの変数 z に対して勾配 ∂y/∂z を求めるのが目的です。これは∂y/∂y=1 から出発して再帰的に勾配を求めることができます。いま、z=f(x) のような関係があるときに ∂y/∂z を表すテンソルがわかっているとすると ∂y/∂x = ∂y/∂z ・ ∂z/∂x = ∂y/∂z ・ F(x) (ここで、F(x) := ∂f(x)/∂x とした) となるため、f に対してその勾配関数 F を事前に計算できる状態にしておけば勾配を計算できます。計算グラフの観点からすると、元の計算グラフ (順伝播部分と呼ぶことにします) から勾配の計算部分(逆伝播部分)を足していることになります。例えば3層のニューラルネットの順伝播部と逆伝播部は以下のような図になります (簡単のため、∂y/∂z を gz のように記しています) 。

再計算

計算グラフは勾配計算のための実行手順を与えてくれますが、これをそのまま実行すると順伝播部分での計算結果は逆伝播時に基本的にすべて必要となるため、単純に中間結果もすべて記憶しておくと、大規模学習ではメモリが足りなくなることがあります。しかしよく考えると順伝播ですべてを記憶せずに一部の中間結果を破棄したとしても、残りの中間結果からもう一度順方向に計算して必要な中間結果を復元さえできれば、逆伝播時に勾配計算を行うことができます。これにより計算のオーバーヘッドが発生する代わりにピーク時のメモリ消費を下げることできます。

このような手法を再計算あるいはチェックポインティング (checkpointing) と呼びます。再計算自体はニューラルネット固有の手法ではなく、自動微分のコミュニティで研究されていました[2][3]。再計算はメモリ消費を抑える代わりに追加の計算時間を発生させます。どの変数をどのタイミングで捨てるかという戦略によってメモリ消費とオーバーヘッドは変わります。近年になってディープラーニングの問題設定に特化した再計算手法が提案されるようになりました[4][5]。

ここではその一つである Chen らの手法 [4] を紹介します。簡単のため、計算グラフが n 層の直線的なネットワークになっている場合を考えます。実際の計算ではモデルパラメータが付いているかもしれませんが一旦無視します。いま、グラフを √n 個ごとに切って √n 個のブロックに分けたとします。順伝播ではそれぞれのブロックを計算した後にブロック間の境界となる部分の変数以外をメモリから捨てることにします。逆伝播では捨てた部分が必要になってしまいますが、残しておいた部分を起点として順伝播のブロックを一時的に復元することでそれぞれのブロック内で逆伝播を実行できます。これにより順伝播部分で再計算のオーバーヘッドが順伝播1回分だけ掛かる代わりに、メモリ消費を O(n) から O(√n) 程度に減らすことができます。ResNet のようにスキップ接続がある場合でも、関節点等でグラフを切れば似たようなことができます。

グラフ的形式化による再計算 (我々の提案手法)

ここからは我々が少し前に arXiv に投稿した論文である “A Graph Theoretic Framework of Recomputation Algorithms for Memory-Efficient Backpropagation” の紹介をします。こちらは2018年夏PFNインターンの井上卓哉さんとの研究成果でもあります。

深層学習で知られている再計算手法は適応可能範囲が計算グラフが限定的で、やや砕けた表現をすると「グラフが直線っぽい場合」に特化していました。しかし近年着目されているネットワークには U-Net のように大きなスキップ接続が存在したりして多様な構造を持っています。また、メモリと計算時間について良いトレードオフを取るという点も大事です。つまりメモリ不足がそこまで深刻でない状況ではできるだけオーバーヘッドを少なくするような再計算スケジュールを求めたいはずです。

そこで我々の論文では、任意の構造の (静的な) 計算グラフ *1 と利用可能なメモリ容量が与えられたときに、メモリ容量を超えない範囲でできるだけオーバーヘッドを小さくするスケジュールを求める離散的な最適化問題を考えます。

任意のグラフに対する再計算も、Chen らの手法の核である「グラフをブロックごとに切ってそれぞれのブロックごとに順伝播、再計算、逆伝播を行う」という考えを拡張できます。すなわち、元の計算グラフの頂点集合 V を V1, V2, …, Vk というブロックに分割し、V1→V2→…→Vk と順伝播計算するものだとします。するとこのような分割方法に対してそれに付随する再計算方法も自然に定まります。砕けた言い方をすると、順伝播で各ブロックを計算し終えた後には境界となるところをだけを覚えて、そうでないところは捨て去るようにします。逆伝播では忘れたところを復元します。よって分割方法を決めればそれに付随する自然な再計算方法の消費メモリとオーバーヘッドが定まります。

分割方法は残念ながら指数的に多く存在するので全探索などはできそうにないですが、もし分割列の途中状態の集合 (V1∪…∪Vi) としてありうるパターン数が少ないのだとすると動的計画法によって最適化問題の解を用いて求めることができます。パターン数が多いときでも、近似的に解くことで現実的に性能の良い解を求める方法も提案しています。

実験では PSPNet, ResNet, DenseNet, U-Net などのネットワークに対して提案手法を用いると計算時間が1.3~1.4倍程度になる代わりに40%-80%のメモリ削減を実現できることや、メモリに余裕がある場合には既存手法よりも計算時間のオーバーヘッドを小さくできることを確認しています。

*1 RNN のようなループを含む計算グラフであっても、ループ回数がイテレーションごとに固定であればループを展開して静的なグラフとみなせます。

Chainer-compiler 上での実装

まだ実験的な段階ではありますが、再計算手法を Chainer の学習で使えるようにする取り組みをしています。再計算では事前に計算グラフの構造が分かっている必要があるため、Chainer 本体ではなく計算グラフのコンパイラである Chainer-compiler 上でその実装を進めています。学習させるときの流れは以下のようになります。

  1. まず Python で記された Chainer のモデルを静的な計算グラフとして ONNX 形式にダンプします。これは ONNX-chainer を使えばできます。
  2. ONNX 形式の計算グラフを Chainer-compiler に渡すと学習のための逆伝播部分を足して勾配計算を実行可能な形式にします(Python からは `chainer.Chain` でラップされた状態で見られます)。オプション次第で再計算を含めたスケジュール生成を自動で行います。

Chainer-compiler には Python ラッパーがあり、元の Python コードに少し変更を加えるだけで使えるような形になっています。もし試してみたい方がいらっしゃったらドキュメントの Train your model with chainer-compiler を参考に実行してみてください。

まとめ

深層学習における再計算という手法の紹介と PFN での取り組みについて紹介しました。メモリ不足が深層学習研究開発のボトルネックにならない世の中が来ると素敵なのかもしれません。

ちなみに手動スケジューリングでいいのであれば、Chainer なら functions.forget を使うと比較的カジュアルに再計算ができます。

文献

[1] Chao Peng, Tete Xiao, Zeming Li, Yuning Jiang, Xiangyu Zhang, Kai Jia, Gang Yu, and Jian Sun. MegDet: A large mini-batch object detector. In IEEE Conference on Computer Vision and Pattern Recognition (CVPR), pages 6181–6189, 2018.

[2] Andreas Griewank and Andrea Walther. Evaluating derivatives: principles and techniques of algorithmic differentiation. Vol. 105. Siam, 2008.

[3] Benjamin Dauvergne and Laurent Hascoët. The data-flow equations of checkpointing in reverse automatic differentiation. International Conference on Computational Science. Springer, Berlin, Heidelberg, 2006.

[4] Tianqi Chen, Bing Xu, Chiyuan Zhang, and Carlos Guestrin. Training deep nets with sublinear memory cost. arXiv preprint, arXiv:1604.06174, 2016.

[5] Audrunas Gruslys, Rémi Munos, Ivo Danihelka, Marc Lanctot, and Alex Graves. Memory-efficient backpropagation through time. In Advances in Neural Information Processing Systems (NIPS), pages 4125–4133, 2016.