2017-05-01 7 views
1

私はpymc3を使って正弦曲線をkeras(theanoバックエンド)モデルに合わせようとしています。私はこれを参照点として使用しています[http://twiecki.github.io/blog/2016/07/05/bayesian-deep-learning/]]。KerasとPYMC3で正弦波を当てると、予期せぬ結果が出る

最適化を使用したKeras実装だけではうまくいきますが、pymc3のHamiltonian Monte CarloとVariationalサンプリングはデータに適合しません。トレースは、事前に開始された場所で止まっています。前に移動すると、後ろの動きは同じ場所に移動します。セル59のベイジアンモデルの事後予測は正弦波をほとんど得ていないが、ベイジアンフィットモデルではセル63では完璧に近づく。私はここにノートブックを作成した。https://gist.github.com/tomc4yt/d2fb694247984b1f8e89cfd80aff8706はコードと結果を示す。ここで

class GaussWeights(object): 
    def __init__(self): 
     self.count = 0 

    def __call__(self, shape, name='w'): 
     return pm.Normal(
      name, mu=0, sd=.1, 
      testval=np.random.normal(size=shape).astype(np.float32), 
      shape=shape) 


def build_ann(x, y, init): 
    with pm.Model() as m: 

     i = Input(tensor=x, shape=x.get_value().shape[1:]) 
     m = i 
     m = Dense(4, init=init, activation='tanh')(m) 
     m = Dense(1, init=init, activation='tanh')(m) 

     sigma = pm.Normal('sigma', 0, 1, transform=None) 
     out = pm.Normal('out', 
         m, 1, 
         observed=y, transform=None) 

    return out 



with pm.Model() as neural_network: 
    likelihood = build_ann(input_var, target_var, GaussWeights()) 

#  v_params = pm.variational.advi(
#   n=300, learning_rate=.4 
# ) 
#  trace = pm.variational.sample_vp(v_params, draws=2000) 
    start = pm.find_MAP(fmin=scipy.optimize.fmin_powell) 
    step = pm.HamiltonianMC(scaling=start) 
    trace = pm.sample(1000, step, progressbar=True) 
+0

あなたは、間違っていると思われることについて具体的に説明できますか?一見すると、2つのモードに問題があるように見えますが、それ以外の場合は問題ありません。 (また、 'シグマ'を定義しますが、どこにも使用しません...) – aseyboldt

+0

@aseyboldt質問を更新しました。主な問題は、事前トレースが開始された場所でトレースが停止していることです。トレースプロットを確認してください。前に移動すると、後ろの動きは同じ場所に移動します。セル59のベイジアンモデルの事後予測は正弦波をほとんど得ていないが、ベイジアンフィットモデルではセル63では完璧に近づく。シグマは使用されていないが問題ではない。 – tomc4yt

+0

あなたのモデルは、測定値がstd = 1のネットワーク出力からの正規分布に従うと言っています。その後、予測的な後部からx値ごとに100個の値をサンプリングし、それらの中央値を取る。それらのサンプルは、各x値に対して1 + posterior_varianceの分散を有する。それらの中央値は、ネットワークからの出力の回りに自然に変化します。モデルがあなたの言うことを正確にしているようです。 – aseyboldt

答えて

1

...以下のモデルの抜粋であるモデルが1の固定STDと、通常のノイズが含まれています

out = pm.Normal('out', m, 1, observed=y) 

が、データセットにはありません。予測的な後方がデータセットと一致しないことは当然のことであり、非常に異なる方法で生成されています。それはより現実的なあなたのデータセットにノイズを追加し、シグマを見積もることができようにするには:

mu = pm.Deterministic('mu', m) 
sigma = pm.HalfCauchy('sigma', beta=1) 
pm.Normal('y', mu=mu, sd=sigma, observed=y) 

あなたが今やっていることは、ネットワークからの出力を取得し、標準正規ノイズを追加することに似ています。

無関係なコメントのカップル:

  • outは、それが再び単なるデータセットで、可能性はありません。
  • NUTSの代わりにHamiltonianMCを使用する場合は、ステップサイズと統合時間を自分で設定する必要があります。デフォルトは通常有用ではありません。
  • ケラスのようなものが2.0で変更されているようですが、pymc3とkerasを組み合わせるこの方法はもう機能していないようです。
+0

これは効果的な解決策ではありませんが、標準偏差が技術的に正しい問題であることを確認しましたので、これを受け入れます。私の前任者は体重の周りにありましたが、あまり指定されていませんでした。このエリアでRadford M Nealの仕事に従って適切なハイパープライヤーを配置すると、より良い結果が得られました。特に、私の前任者は検索スペースを制限していました。私は重みの標準devを広げる必要がありました – tomc4yt

関連する問題