فجورد

عرض على TensorFlow.org تشغيل في Google Colab عرض المصدر على جيثب تحميل دفتر

يثبت

أول تثبيت الحزم المستخدمة في هذا العرض.

pip install -q dm-sonnet

الواردات (tf ، tfp مع الخدعة المساعدة ، إلخ)

import numpy as np
import tqdm as tqdm
import sklearn.datasets as skd

# visualization
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import kde

# tf and friends
import tensorflow.compat.v2 as tf
import tensorflow_probability as tfp
import sonnet as snt
tf.enable_v2_behavior()

tfb = tfp.bijectors
tfd = tfp.distributions

def make_grid(xmin, xmax, ymin, ymax, gridlines, pts):
  xpts = np.linspace(xmin, xmax, pts)
  ypts = np.linspace(ymin, ymax, pts)
  xgrid = np.linspace(xmin, xmax, gridlines)
  ygrid = np.linspace(ymin, ymax, gridlines)
  xlines = np.stack([a.ravel() for a in np.meshgrid(xpts, ygrid)])
  ylines = np.stack([a.ravel() for a in np.meshgrid(xgrid, ypts)])
  return np.concatenate([xlines, ylines], 1).T

grid = make_grid(-3, 3, -3, 3, 4, 100)
/usr/local/lib/python3.6/dist-packages/statsmodels/tools/_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.
  import pandas.util.testing as tm

وظائف المساعد للتصور

حاقن FFJORD

في هذا colab ، نعرض أداة bijector FFJORD ، التي تم اقتراحها في الأصل في الورقة بواسطة Grathwohl ، Will ، et al. أرخايف الارتباط .

في باختصار الفكرة من وراء هذا النهج هو إقامة المراسلات بين توزيع قاعدة معروفة وتوزيع البيانات.

لإنشاء هذا الاتصال ، نحتاج إلى

  1. تحديد bijective خريطة \(\mathcal{T}_{\theta}:\mathbf{x} \rightarrow \mathbf{y}\)، \(\mathcal{T}_{\theta}^{1}:\mathbf{y} \rightarrow \mathbf{x}\) بين الفضاء \(\mathcal{Y}\) الذي يعرف توزيع قاعدة والفضاء \(\mathcal{X}\) المجال البيانات.
  2. الحفاظ بكفاءة مسار التشوهات نقوم بتحويل فكرة احتمال على \(\mathcal{X}\).

ورسميا الشرط الثاني في التعبير التالي للتوزيع احتمال المعرفة على \(\mathcal{X}\):

\[ \log p_{\mathbf{x} }(\mathbf{x})=\log p_{\mathbf{y} }(\mathbf{y})-\log \operatorname{det}\left|\frac{\partial \mathcal{T}_{\theta}(\mathbf{y})}{\partial \mathbf{y} }\right| \]

يقوم برنامج التحوّل FFJORD بتحقيق ذلك من خلال تحديد عملية تحويل

\[ \mathcal{T_{\theta} }: \mathbf{x} = \mathbf{z}(t_{0}) \rightarrow \mathbf{y} = \mathbf{z}(t_{1}) \quad : \quad \frac{d \mathbf{z} }{dt} = \mathbf{f}(t, \mathbf{z}, \theta) \]

هذا التحول هو للانعكاس، طالما وظيفة \(\mathbf{f}\) يصف تطور الدولة \(\mathbf{z}\) وحسن تصرف و log_det_jacobian يمكن أن تحسب من خلال دمج التعبير التالي.

\[ \log \operatorname{det}\left|\frac{\partial \mathcal{T}_{\theta}(\mathbf{y})}{\partial \mathbf{y} }\right| = -\int_{t_{0} }^{t_{1} } \operatorname{Tr}\left(\frac{\partial \mathbf{f}(t, \mathbf{z}, \theta)}{\partial \mathbf{z}(t)}\right) d t \]

في هذا العرض سوف نقوم تدريب bijector FFJORD إلى تشوه توزيع الضبابي على توزيع يحددها moons البيانات. سيتم ذلك في 3 خطوات:

  • تحديد توزيع قاعدة
  • تحديد جامع FFJORD
  • تقليل احتمالية السجل الدقيقة لمجموعة البيانات

أولاً ، نقوم بتحميل البيانات

مجموعة البيانات

بي إن جي

بعد ذلك ، نقوم بإنشاء مثيل التوزيع الأساسي

base_loc = np.array([0.0, 0.0]).astype(np.float32)
base_sigma = np.array([0.8, 0.8]).astype(np.float32)
base_distribution = tfd.MultivariateNormalDiag(base_loc, base_sigma)

ونحن نستخدم متعدد الطبقات المستقبلات إلى نموذج state_derivative_fn .

في حين ليس من الضروري لهذه البينات، غالبا ما يكون benefitial لجعل state_derivative_fn تعتمد على الوقت. نحن هنا تحقيق ذلك عن طريق وصل t على المدخلات من شبكتنا.

class MLP_ODE(snt.Module):
  """Multi-layer NN ode_fn."""
  def __init__(self, num_hidden, num_layers, num_output, name='mlp_ode'):
    super(MLP_ODE, self).__init__(name=name)
    self._num_hidden = num_hidden
    self._num_output = num_output
    self._num_layers = num_layers
    self._modules = []
    for _ in range(self._num_layers - 1):
      self._modules.append(snt.Linear(self._num_hidden))
      self._modules.append(tf.math.tanh)
    self._modules.append(snt.Linear(self._num_output))
    self._model = snt.Sequential(self._modules)

  def __call__(self, t, inputs):
    inputs = tf.concat([tf.broadcast_to(t, inputs.shape), inputs], -1)
    return self._model(inputs)

معلمات النموذج والتدريب

الآن نقوم ببناء كومة من عوامل التحفيز FFJORD. وتقدم كل bijector مع ode_solve_fn و trace_augmentation_fn وانها الخاصة state_derivative_fn نموذج، بحيث تمثل سلسلة من التحولات المختلفة.

بناء bijector

الآن يمكننا استخدام TransformedDistribution الذي هو نتيجة لتزييفها base_distribution مع stacked_ffjord bijector.

transformed_distribution = tfd.TransformedDistribution(
    distribution=base_distribution, bijector=stacked_ffjord)

الآن نحدد إجراءات التدريب لدينا. نقوم ببساطة بتقليل احتمالية السجل السلبي للبيانات.

تمرين

عينات

ارسم عينات من التوزيعات الأساسية والتوزيعات المحولة.

evaluation_samples = []
base_samples, transformed_samples = get_samples()
transformed_grid = get_transformed_grid()
evaluation_samples.append((base_samples, transformed_samples, transformed_grid))
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow/python/ops/resource_variable_ops.py:1817: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.
panel_id = 0
panel_data = evaluation_samples[panel_id]
fig, axarray = plt.subplots(
  1, 4, figsize=(16, 6))
plot_panel(
    grid, panel_data[0], panel_data[2], panel_data[1], moons, axarray, False)
plt.tight_layout()

بي إن جي

learning_rate = tf.Variable(LR, trainable=False)
optimizer = snt.optimizers.Adam(learning_rate)

for epoch in tqdm.trange(NUM_EPOCHS // 2):
  base_samples, transformed_samples = get_samples()
  transformed_grid = get_transformed_grid()
  evaluation_samples.append(
      (base_samples, transformed_samples, transformed_grid))
  for batch in moons_ds:
    _ = train_step(optimizer, batch)
0%|          | 0/40 [00:00<?, ?it/s]
WARNING:tensorflow:From /usr/local/lib/python3.6/dist-packages/tensorflow_probability/python/math/ode/base.py:350: calling while_loop_v2 (from tensorflow.python.ops.control_flow_ops) with back_prop=False is deprecated and will be removed in a future version.
Instructions for updating:
back_prop=False is deprecated. Consider using tf.stop_gradient instead.
Instead of:
results = tf.while_loop(c, b, vars, back_prop=False)
Use:
results = tf.nest.map_structure(tf.stop_gradient, tf.while_loop(c, b, vars))
100%|██████████| 40/40 [07:00<00:00, 10.52s/it]
panel_id = -1
panel_data = evaluation_samples[panel_id]
fig, axarray = plt.subplots(
  1, 4, figsize=(16, 6))
plot_panel(grid, panel_data[0], panel_data[2], panel_data[1], moons, axarray)
plt.tight_layout()

بي إن جي

يؤدي تدريبه لفترة أطول مع معدل التعلم إلى مزيد من التحسينات.

غير متقارب في هذا المثال ، يدعم عنصر التحيز FFJORD تقدير التتبع العشوائي لهتشينسون. يمكن توفير مقدر معين عبر trace_augmentation_fn . وبالمثل تكامل بديلة يمكن استخدامها عن طريق تحديد مخصص ode_solve_fn .