Deprecated : The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
Google Developers Japan: TensorFlow Probability
この記事は Dave Moore、Jacob Burnim と TFP チームによる TensorFlow - Medium の記事 "Structural Time Series modeling in TensorFlow Probability " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
投稿者: Dave Moore、Jacob Burnim と TFP チーム
本投稿では、TensorFlow Probability の新しいライブラリ tfp.sts について紹介します。このライブラリは、構造時系列モデルを使って時系列を予測します [3]。
概要
「予想とは難しいものだ。特に未来に関しては」
— Karl Kristian Steincke
未来の出来事の予想はどうしても不確かなものになりますが、予測なしに将来の計画を立てることはできません。ウェブサイトの所有者は、サイトにアクセスするユーザーの数を予測して十分なハードウェア リソースを準備しなければなりません。また将来の収益や費用も予想する必要があります。企業は消費者製品の将来の需要を予測し、十分な在庫を確保する必要があります。電力会社は、電気の需要を予測し、その情報に基づいて電力の購買契約を結んだり、新しい発電所を建設したりする必要があります。
時系列を予測する手法は、ある機能をリリースした際のユーザー エンゲージメントへの影響など、何らかの変化が起きた場合の影響の推論に利用できます [1]。また、現在の失業率のような観測が難しい値をより入手しやすい情報から推論したり [2]、時系列データの異常値を検出したりするためにも用いられます。
構造時系列モデル
構造時系列(STS)モデル [3] は時系列を扱う確率モデルの一種で、次のような多くの標準的な時系列モデルの考え方を取り入れて汎用化したものです。
自己回帰プロセス
移動平均
ローカル線形トレンド
周期性
外部共変量(関心対象の時系列に関係する可能性がある他の時系列)に対する回帰と変数選択
STS モデルは、観測された時系列をより簡単な構成要素の合計として表現します。
それぞれの構成要素は、特定の構造を仮定して得られる時系列です。たとえば、いくつかの共変量時系列に対して、ある要素は周期的影響(例: 曜日による影響)を、別の要素はローカル線形トレンドを、さらに別の要素は線形依存性を表せます。
構造時系列を使うと、モデル作成者がデータの生成プロセスについての仮定を表現できるので、かなり少ないデータ(例えばデータが数 10 個しかない入力系列ひとつ)からでも妥当な予測をしやすくなります。また、過去のデータや将来の予測を構造化された要素へ分解、視覚化すれば、モデルによる予想の解釈も可能です。さらに確率的なモデリングによって、欠落したデータを自然に処理でき、一定の原則に基づいて「不確かさ」を定量的に扱えます。
TensorFlow Probability の構造時系列
TensorFlow Probability(TFP)は現在、構造時系列モデルを使ったフィッティングや予測を標準でサポートしています。変分推論(VI)やハミルトニアン・モンテカルロ法(HMC)を使ったモデル パラメーターのベイズ推論などがサポートされており、点推定と不確かさの推定の両方を計算できます。TensorFlow を使って構築されているので、これらの手法はそのままでもベクトル ハードウェア(GPU や TPU)のメリットを活用でき、多くの時系列を効率的かつ並列に処理したり、ディープ ニューラル ネットワークと統合したりできます。
例: CO2 濃度の予測
実際の構造時系列の例として、ハワイのマウナロア観測所で月ごとに記録した大気中の CO2 濃度について考えてみます [5]。
このように、この時系列には、長期的なトレンドと季節による年次変動の両方が含まれています。この 2 つの構成要素は、わずか数行の TFP コードを使って構造時系列モデルで直接表現できます。
ここでは、ローカル線形トレンドモデルを使います。このモデルは、トレンドが線形で、ランダム ウォークにしたがって時間とともにゆっくりと変化する傾きを持つと仮定しています。モデルをデータにフィッティングさせると、モデルの仮定に基づいた確率的予測が生成されます。
この線形トレンドモデルでは、時間とともに予測の不確実性(標準偏差 ± 2 で網掛け)が増加しています。これは、傾きを補間する際の信頼度が小さくなっていくためです。予測の中央値は、既存トレンドを線形的に補間したものと、季節変動を組み合わせたものになっています。大気中の CO2 濃度の増加は加速しており、その点がわずかに過小評価されていますが、実際の値は 95% の予測区間内にあります。
この例のコード は、すべて Github で公開されています。
例: 電気の需要予測
次に、もう少し複雑な例について考えてみます。オーストラリアのビクトリア州の電力需要予測です。上のグラフは、2014 年最初の 6 週間の 1 時間ごとの記録です([4] のデータ、https://github.com/robjhyndman/fpp2-package で公開されているもの)。
ここでは。冷房用の電気の需要と相関関係がある気温のデータを外部からのデータとして利用します(オーストラリアでは 1 月は夏であることに注意しましょう)。この気温データを STS モデルに組み込みます。STS モデルには、線形回帰を通して外部共変量を含めることができます。
ここでは、複数の周期的影響を含めている点に注意してください。時間と曜日による影響に加え、説明できないその他の影響をモデリングするための自己回帰コンポーネントも加えています。単純なランダム ウォークも使えますが、分散を一定に抑えるため自己回帰コンポーネントを選んでいます。
このモデルによる予測は完璧ではなく、まだモデリングできていない何らかの要因がありそうです。しかし、まったくの的外れではなく、不確定性も妥当な範囲に収まっているように見えます。予測を個々の要素に分解して視覚化すると、これをよりよく理解することができます(グラフの y 軸のスケールは要素によって異なります)。
このモデルは、時間による大きな影響と、曜日による小さな影響(土曜日と日曜日に需要が最も低くなる)、さらに気温によるかなり大きな影響を相当正確に特定しています。これらの影響からは、かなり信頼性の高い予測を行っています。予想の不確定性の大部分は、観測された時系列におけるモデリングできない(その他の)変動を予測する自己回帰プロセスによるものです。
モデル作成者は、このような個々の要素への分解によってモデルの改善方法を知ることができます。たとえば上図では、自己回帰のスパイクは気温のスパイクと重なっている部分があります。つまり、特徴量やデータ変換をさらに追加すれば、気温による影響をもう少し正確にモデル化できるかもしれません。
この例のコード は、すべて Github で公開されています。
TensorFlow Probability STS ライブラリ
以上の例からわかるように、TFP ではモデルの構成要素を組み合わせて STS モデルを構築できます。STS は、次のようなモデルの要素を提供しています。
STS は、変分推論 とハミルトニアン・モンテカルロ法 を使って結果の時系列モデルをフィッティングする手法を提供します。
TFP ホームページ で、コードやドキュメント、その他の例をご覧ください。
構造時系列は、Google 内部でもいくつかの重要な時系列に応用されています。構造時系列が皆さんにも役立つことを期待しています。最新の Tensorflow Probability のお知らせや、その他の TFP に関するディスカッションに興味がある方は、tfprobability@tensorflow.org フォーラムに参加してください。
参考文献
[1] Brodersen, K. H., Gallusser, F., Koehler, J., Remy, N., & Scott, S. L. (2015). Inferring causal impact using Bayesian structural time-series models. The Annals of Applied Statistics , 9 (1), 247–274.
[2] Choi, H., & Varian, H. (2012). Predicting the present with Google Trends. Economic Record, 88, 2–9.
[3] Harvey, A. C. (1989). Forecasting, structural time series models and the Kalman filter . Cambridge University Press.
[4] Hyndman, R.J., & Athanasopoulos, G. (2018). Forecasting: principles and practice, 2nd edition, OTexts: Melbourne, Australia. OTexts.com/fpp2. Accessed on February 23, 2019.
[5] Keeling, C. D., Piper, S. C., Bacastow, R. B., Wahlen, M., Whorf, T. P., Heimann, M., & Meijer, H. A. (2001). Exchanges of atmospheric CO2 and 13CO2 with the terrestrial biosphere and oceans from 1978 to 2000. I. Global aspects, SIO Reference Series, №01–06, Scripps Institution of Oceanography, San Diego.
Reviewed by Kaz Sato - Staff Developer Advocate, Google Cloud
この記事は Ian Fischer、Alex Alemi、Joshua V. Dillon と TFP チーム による TensorFlow - Medium の記事 "Variational Autoencoders with Tensorflow Probability Layers " を元に翻訳・加筆したものです。詳しくは元記事をご覧ください。
投稿者: Ian Fischer、Alex Alemi、Joshua V. Dillon と TFP チーム
2019 年の TensorFlow Developer Summit では、TensorFlow Probability(TFP)が発表されました 。その際のプレゼンテーションでは、ほんのわずかなコードで強力な回帰モデルを構築する方法を紹介しました。この記事では、TFP を使うことで変分オートエンコーダ(VAE)の実装がどれだけ簡単になるかを解説します。
TensorFlow Probability
TFP は、Keras とディープ ネットワークを使って確率分布を生成する高レベル API を提供します。この API を使うと、ディープ ラーニングと確率的プログラミングを組み合わせたモデルを簡単に構築できます。たとえば、確率分布のパラメータを決めるのにディープ ネットワークの出力を使えます。以下では、この TFP のアプローチを紹介します。
変分オートエンコーダと ELBO
変分 オートエンコーダ (VAE)は、協調フィルタリング 、イメージ圧縮 、強化学習 、音楽 やスケッチ の生成などのさまざまな領域で使われいるポピュラーな生成モデルです。
VAE の応用といえば、潜在変数による生成モデルなどのデータ生成が思い浮かびます。そこで、MNIST にある数字を書く処理について考えてみましょう。
あなたがペンで数字を書くとき、まずはどの数字を書くかを決め、頭の中で漠然とした図を思い浮かべるはずです。次に、ペンを紙につけて、実際の世界でその図を描こうとします。この 2 つのステップは、次のように定義できます。
サンプルとして、 潜在表現 z を選びます。これは、事前確率分布 z ~ p (z ) の中から選ばれます。これが、頭の中にある漠然とした図です。ここでは、「3」としましょう。
サンプルに基づき、実際の図としての表現 x を書きます。これは、自身を確率過程 x ~ p (x|z ) としてモデリングしたものです。これにより、「3」を書くたびに少しずつ違ったものができる仕組みを表せます。
このように、手書き数字を書くときに毎回生じる変化について、そのある部分は何らかのシグナル (例えば MNIST の数字の種類)によるものであり、その他の部分はノイズ によるものと考えます。例えば同じ人が書いた同じ数字のサンプルでも、厳密な線の角度は毎回異なります。VAE とは、大まかに言えば、このシグナルとノイズのそれぞれについて明確なモデルを与え、ノイズからシグナルを分離しようという試みです。
この考えに基づいた学習を行うために、次の ELBO(変分下限)を最大化する損失関数を定義します。
ここで、3 つの確率密度関数は以下を表します。
p (z ) - 潜在表現 z の事前確率
q (z|x ) - 変分エンコーダ
p (x|z ) - デコーダ — 潜在的表現 z が与えられた場合の画像 x の確率
ELBO は、観測されたデータポイントの対数確率 log p (x ) の下限を表します。この式の最初の積分は、復元 項です。画像 x が z にエンコードされ、さらにデコードされて元の x を復元できる確率を表します。第 2 項は、 KL ダイバージェンス 項です 。エンコーダと事前確率がどのくらい近いかを測る式であり、エンコーダのシンプルさを保つためのものと言えます。ある事前確率のもとで尤度の低い z をエンコーダが生成すると、ELBO の値も低くなります。そのため、エンコーダーと事前確率に差が生じるのは、復元項を上回る効果が得られる場合に限られます。
コード
以上の説明から、 事前確率 p(z) 、 変分エンコーダ q(z|x) 、 デコーダ p(x|z) という 3 つの異なるコンポーネントを個々にモデリングする方法が自然だとわかります。こちらの colab を使うと、MNIST に対する VAE の学習をクラウド上の GPU で数分で実行できます。
事前確率
通常、VAE で使われる最も単純な事前確率は、等方性ガウス分布です。
ここでは、学習パラメータのない独立したガウス分布を TFP で定義し、潜在変数 z が 16 次元となるように指定しています。
エンコーダ
エンコーダ分布には、完全共分散ガウス分布を使います。平均および共分散行列は、ニューラル ネットワークの出力によってパラメータ化されています。複雑に聞こえるかもしれませんが、TFP レイヤーを使えばとても簡単に表現できます。
エンコーダは通常の Keras Sequential モデルで、畳み込み層と全結合層からできています。ただし、出力は TFP レイヤー MultivariateNormalTril() に渡されます。これは、最後の Dense() 層による活性化を、Multivariate Normal のパラメータとなる平均および(下三角)共分散行列の両方を指定するために必要な部分へとそのまま分割します。Dense() 層に正しい数の活性化(分布のパラメータ)を出力させるために、ヘルパー tfpl.MultivariateNormalTriL.params_size(encoded_size) を使いました。最後に、分布が最終的な損失に対する正則化項として寄与するよう指定します。具体的には、エンコーダと事前確率との間の KL ダイバージェンスを追加します。これは、前述の ELBO の KL 項 です(ちなみに、引数 weight を 1 以外のものに変えるだけで、この VAE を β -VAE に変更できます)。
デコーダ
デコーダには、単純な「平均場デコーダ」を使います。今回の場合、これはピクセル間で独立したベルヌーイ分布になります。
この書き方は基本的にエンコーダと同じです。しかし、潜在表現を取得するために転置した畳み込み(16 次元ベクトル)を使っているので、それを 28 x 28 x 1 のテンソルに変換します。最終的なテンソルは、ピクセル間で独立したベルヌーイ分布のパラメータを表します。
損失関数
ここまでで、完全なモデルを構築して残りの損失関数を指定する準備ができました。
このモデルは、エンコーダとデコーダの組み合わせを出力として指定した単純な Keras モデルです。エンコーダ部分ですでに損失として KL 項を追加しているので、指定する必要があるのは復元項だけです(前述の ELBO の第 1 項)。
この損失関数には、2 つの引数があります。元の入力 x と、モデルの出力です。これは確率変数なので rv_x と記しています。この例は、TFP レイヤーの内側でどのような「魔法」が働いているか表しています。Keras と TensorFlow からは、TFP が単にテンソルを出力するレイヤーとして見える一方で、TFP レイヤーの実際の中身は Distribution オブジェクトで構成されています。そのため、モデルに与えられたデータに対する負の対数尤度 -rv_x.log_prob(x) を損失関数として指定できる仕組みです。
TFP の内側
Keras の中にシームレスに組み込まれた TFP レイヤーが実際にどのような処理を実行しているのか、もう少し詳しく見てみましょう。前述のように、TFP レイヤーは実際には Distribution オブジェクトを出力します。これは、次のコードで確かめることができます。
しかし、TFP レイヤーが Distribution を返すとすれば、decoder_model(encoder_model.outputs[0])) と書いてエンコーダの出力とデコーダを組み合わせる際には何が起きているのでしょうか。エンコーダの返す Distributionが Keras からは Tensor として見えるようにするため、TFP レイヤーはその分布から具体的なデータポイントをサンプリングします。つまり Keras が見ているのは、Distribution に対して encoder_model.sample() を呼んだときに得られる Tensor です。一方で、損失関数で rv_x.log_prob(x) を呼び出すときのように、Distribution として直接アクセスする必要がある場合は、そうすることも可能です。TFP レイヤーは、確率分布としてもテンソルとしてもふるまえるので、Keras の中でシームレスに取り扱えます。
モデルの学習
このモデルの学習は、Keras モデルの学習と同じように簡単で、vae_model.fit() を呼ぶだけです。
このモデルでは、およそ 115 nat の ELBO を実現できます( nat はビットの自然対数です。115 nat はおよそ 165 ビット)。もちろん、これは最高のパフォーマンスというわけではありません。しかし、3 つのコンピューティングのいずれについても、この基本設定から始めて、簡単に強化できます。それに、このままでもすでに数字を生成してくれます。
MNIST テストセットのイメージをエンコードして生成したデコーダ最頻値 事前確率をサンプリングして生成したデコーダ最頻値
まとめ
このブログ記事では、ディープ ラーニングと確率的プログラミングを組み合わせる方法について紹介し、TFP レイヤーを使って Keras の Sequential モデルの出力を TFP の確率分布に渡す VAE を構築しました。テンソルとしても確率分布としてもふるまえる TFP レイヤーを用いることで、シンプルなコードを記述できることがお分かりいただけたと思います。
Reviewed by Kaz Sato - Staff Developer Advocate, Google Cloud