مساعدة في حماية الحاجز المرجاني العظيم مع TensorFlow على Kaggle تاريخ التحدي

تركيب نموذج خليط عملية Dirichlet باستخدام ديناميكيات Langevin المتدرجة العشوائية المشروطة مسبقًا

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

في هذا الكمبيوتر الدفتري ، سنشرح كيفية تجميع عدد كبير من العينات واستنتاج عدد المجموعات في وقت واحد من خلال تركيب مزيج عملية Dirichlet لتوزيع Gaussian. نحن نستخدم ديناميكيات لانجفين المتدرجة العشوائية المشروطة مسبقًا (pSGLD) للاستدلال.

جدول المحتويات

  1. عينات

  2. نموذج

  3. الاقوي

  4. تصور النتيجة

    4.1 نتيجة مجمعة

    4.2 تصور عدم اليقين

    4.3 يعني وحجم مكون الخليط المختار

    4.4 وزن الخليط لكل مكون من مكونات الخليط

    4.5 تقارب \(\alpha\)

    4.6 العدد المستنتج من الكتل على التكرارات

    4.7 تركيب النموذج باستخدام RMSProp

  5. استنتاج


1. العينات

أولاً ، قمنا بإعداد مجموعة بيانات لعبة. نقوم بتوليد 50000 عينة عشوائية من ثلاثة توزيعات غاوسية ثنائية المتغير.

import time
import numpy as np
import matplotlib.pyplot as plt
import tensorflow.compat.v1 as tf
import tensorflow_probability as tfp
plt.style.use('ggplot')
tfd = tfp.distributions
def session_options(enable_gpu_ram_resizing=True):
  """Convenience function which sets common `tf.Session` options."""
  config = tf.ConfigProto()
  config.log_device_placement = True
  if enable_gpu_ram_resizing:
    # `allow_growth=True` makes it possible to connect multiple colabs to your
    # GPU. Otherwise the colab malloc's all GPU ram.
    config.gpu_options.allow_growth = True
  return config

def reset_sess(config=None):
  """Convenience function to create the TF graph and session, or reset them."""
  if config is None:
    config = session_options()
  tf.reset_default_graph()
  global sess
  try:
    sess.close()
  except:
    pass
  sess = tf.InteractiveSession(config=config)
# For reproducibility
rng = np.random.RandomState(seed=45)
tf.set_random_seed(76)

# Precision
dtype = np.float64

# Number of training samples
num_samples = 50000

# Ground truth loc values which we will infer later on. The scale is 1.
true_loc = np.array([[-4, -4],
                     [0, 0],
                     [4, 4]], dtype)

true_components_num, dims = true_loc.shape

# Generate training samples from ground truth loc
true_hidden_component = rng.randint(0, true_components_num, num_samples)
observations = (true_loc[true_hidden_component]
                + rng.randn(num_samples, dims).astype(dtype))
# Visualize samples
plt.scatter(observations[:, 0], observations[:, 1], 1)
plt.axis([-10, 10, -10, 10])
plt.show()

بي إن جي

2. النموذج

هنا ، نحدد مزيج عملية Dirichlet للتوزيع Gaussian مع Dirichlet Pre المتماثل. في جميع أنحاء دفتر الملاحظات ، تمت كتابة كميات المتجهات بالخط العريض. أكثر من \(i\in\{1,\ldots,N\}\) عينات، ونموذج بمزيج من \(j \in\{1,\ldots,K\}\) وضعت توزيعات جاوس على النحو التالي:

\[\begin{align*} p(\boldsymbol{x}_1,\cdots, \boldsymbol{x}_N) &=\prod_{i=1}^N \text{GMM}(x_i), \\ &\,\quad \text{with}\;\text{GMM}(x_i)=\sum_{j=1}^K\pi_j\text{Normal}(x_i\,|\,\text{loc}=\boldsymbol{\mu_{j} },\,\text{scale}=\boldsymbol{\sigma_{j} })\\ \end{align*}\]

أين:

\[\begin{align*} x_i&\sim \text{Normal}(\text{loc}=\boldsymbol{\mu}_{z_i},\,\text{scale}=\boldsymbol{\sigma}_{z_i}) \\ z_i &= \text{Categorical}(\text{prob}=\boldsymbol{\pi}),\\ &\,\quad \text{with}\;\boldsymbol{\pi}=\{\pi_1,\cdots,\pi_K\}\\ \boldsymbol{\pi}&\sim\text{Dirichlet}(\text{concentration}=\{\frac{\alpha}{K},\cdots,\frac{\alpha}{K}\})\\ \alpha&\sim \text{InverseGamma}(\text{concentration}=1,\,\text{rate}=1)\\ \boldsymbol{\mu_j} &\sim \text{Normal}(\text{loc}=\boldsymbol{0}, \,\text{scale}=\boldsymbol{1})\\ \boldsymbol{\sigma_j} &\sim \text{InverseGamma}(\text{concentration}=\boldsymbol{1},\,\text{rate}=\boldsymbol{1})\\ \end{align*}\]

هدفنا هو تعيين كل \(x_i\) إلى \(j\)عشر العنقودية من خلال \(z_i\) الذي يمثل مؤشر يستدل من كتلة.

للمثالية ديريتشليت خليط النموذجي، \(K\) ومن المقرر أن \(\infty\). ومع ذلك، فمن المعروف أن واحدا يمكن تقريب خليط نموذج ديريتشليت مع كبير بما فيه الكفاية \(K\). لاحظ أن على الرغم من أننا ضبط تعسفي قيمة أولية من \(K\)، والاستدلال على العدد الأمثل من مجموعات أيضا من خلال التحسين، وعلى عكس بسيط جاوس خليط النموذجي.

في هذه المفكرة، ونحن نستخدم توزيع جاوس ثنائية المتغيرات كمكون الخليط ومجموعة \(K\) إلى 30.

reset_sess()

# Upperbound on K
max_cluster_num = 30

# Define trainable variables.
mix_probs = tf.nn.softmax(
    tf.Variable(
        name='mix_probs',
        initial_value=np.ones([max_cluster_num], dtype) / max_cluster_num))

loc = tf.Variable(
    name='loc',
    initial_value=np.random.uniform(
        low=-9, #set around minimum value of sample value
        high=9, #set around maximum value of sample value
        size=[max_cluster_num, dims]))

precision = tf.nn.softplus(tf.Variable(
    name='precision',
    initial_value=
    np.ones([max_cluster_num, dims], dtype=dtype)))

alpha = tf.nn.softplus(tf.Variable(
    name='alpha',
    initial_value=
    np.ones([1], dtype=dtype)))

training_vals = [mix_probs, alpha, loc, precision]


# Prior distributions of the training variables

#Use symmetric Dirichlet prior as finite approximation of Dirichlet process.
rv_symmetric_dirichlet_process = tfd.Dirichlet(
    concentration=np.ones(max_cluster_num, dtype) * alpha / max_cluster_num,
    name='rv_sdp')

rv_loc = tfd.Independent(
    tfd.Normal(
        loc=tf.zeros([max_cluster_num, dims], dtype=dtype),
        scale=tf.ones([max_cluster_num, dims], dtype=dtype)),
    reinterpreted_batch_ndims=1,
    name='rv_loc')


rv_precision = tfd.Independent(
    tfd.InverseGamma(
        concentration=np.ones([max_cluster_num, dims], dtype),
        rate=np.ones([max_cluster_num, dims], dtype)),
    reinterpreted_batch_ndims=1,
    name='rv_precision')

rv_alpha = tfd.InverseGamma(
    concentration=np.ones([1], dtype=dtype),
    rate=np.ones([1]),
    name='rv_alpha')

# Define mixture model
rv_observations = tfd.MixtureSameFamily(
    mixture_distribution=tfd.Categorical(probs=mix_probs),
    components_distribution=tfd.MultivariateNormalDiag(
        loc=loc,
        scale_diag=precision))

3. التحسين

نقوم بتحسين النموذج باستخدام ديناميكيات Langevin المتدرجة العشوائية المشروطة مسبقًا (pSGLD) ، والتي تمكننا من تحسين نموذج على عدد كبير من العينات بطريقة نزول دفعة صغيرة.

إلى المعلمات تحديث \(\boldsymbol{\theta}\equiv\{\boldsymbol{\pi},\,\alpha,\, \boldsymbol{\mu_j},\,\boldsymbol{\sigma_j}\}\) في \(t\,\)عشر التكرار مع مصغرة دفعة حجم \(M\)، وأخذ عينات التحديث على النحو التالي:

$$\begin{align*} \Delta \boldsymbol { \theta } _ { t } & \sim \frac { \epsilon _ { t } } { 2 } \bigl[ G \left( \boldsymbol { \theta } _ { t } \right) \bigl( \nabla _ { \boldsymbol { \theta } } \log p \left( \boldsymbol { \theta } _ { t } \right)

  • \frac { N } { M } \sum _ { k = 1 } ^ { M } \nabla _ \boldsymbol { \theta } \log \text{GMM}(x_{tk})\bigr) + \sum\boldsymbol{\theta}\nabla_\theta G \left( \boldsymbol { \theta } _ { t } \right) \bigr]\ &+ G ^ { \frac { 1 } { 2 } } \left( \boldsymbol { \theta } _ { t } \right) \text { Normal } \left( \text{loc}=\boldsymbol{0} ,\, \text{scale}=\epsilon _ { t }\boldsymbol{1} \right)\ \end{align*}$$

في المعادلة المذكورة أعلاه، \(\epsilon _ { t }\) هو معدل في التعلم \(t\,\)عشر التكرار و \(\log p(\theta_t)\) هو مجموع التوزيعات سجل مسبقة من \(\theta\). \(G ( \boldsymbol { \theta } _ { t })\) هو preconditioner الذي يضبط حجم الانحدار من كل معلمة.

# Learning rates and decay
starter_learning_rate = 1e-6
end_learning_rate = 1e-10
decay_steps = 1e4

# Number of training steps
training_steps = 10000

# Mini-batch size
batch_size = 20

# Sample size for parameter posteriors
sample_size = 100

سوف نستخدم احتمال السجل المشترك لاحتمال \(\text{GMM}(x_{t_k})\) والاحتمالات السابقة \(p(\theta_t)\) عن وظيفة خسارة pSGLD.

علما بأن على النحو المحدد في API من pSGLD ، ونحن بحاجة لتقسيم مجموع الاحتمالات مسبقة من حجم العينة \(N\).

# Placeholder for mini-batch
observations_tensor = tf.compat.v1.placeholder(dtype, shape=[batch_size, dims])

# Define joint log probabilities
# Notice that each prior probability should be divided by num_samples and
# likelihood is divided by batch_size for pSGLD optimization.
log_prob_parts = [
    rv_loc.log_prob(loc) / num_samples,
    rv_precision.log_prob(precision) / num_samples,
    rv_alpha.log_prob(alpha) / num_samples,
    rv_symmetric_dirichlet_process.log_prob(mix_probs)[..., tf.newaxis]
    / num_samples,
    rv_observations.log_prob(observations_tensor) / batch_size
]
joint_log_prob = tf.reduce_sum(tf.concat(log_prob_parts, axis=-1), axis=-1)
# Make mini-batch generator
dx = tf.compat.v1.data.Dataset.from_tensor_slices(observations)\
  .shuffle(500).repeat().batch(batch_size)
iterator = tf.compat.v1.data.make_one_shot_iterator(dx)
next_batch = iterator.get_next()

# Define learning rate scheduling
global_step = tf.Variable(0, trainable=False)
learning_rate = tf.train.polynomial_decay(
    starter_learning_rate,
    global_step, decay_steps,
    end_learning_rate, power=1.)

# Set up the optimizer. Don't forget to set data_size=num_samples.
optimizer_kernel = tfp.optimizer.StochasticGradientLangevinDynamics(
    learning_rate=learning_rate,
    preconditioner_decay_rate=0.99,
    burnin=1500,
    data_size=num_samples)

train_op = optimizer_kernel.minimize(-joint_log_prob)

# Arrays to store samples
mean_mix_probs_mtx = np.zeros([training_steps, max_cluster_num])
mean_alpha_mtx = np.zeros([training_steps, 1])
mean_loc_mtx = np.zeros([training_steps, max_cluster_num, dims])
mean_precision_mtx = np.zeros([training_steps, max_cluster_num, dims])

init = tf.global_variables_initializer()
sess.run(init)

start = time.time()
for it in range(training_steps):
  [
      mean_mix_probs_mtx[it, :],
      mean_alpha_mtx[it, 0],
      mean_loc_mtx[it, :, :],
      mean_precision_mtx[it, :, :],
      _
  ] = sess.run([
      *training_vals,
      train_op
  ], feed_dict={
      observations_tensor: sess.run(next_batch)})

elapsed_time_psgld = time.time() - start
print("Elapsed time: {} seconds".format(elapsed_time_psgld))

# Take mean over the last sample_size iterations
mean_mix_probs_ = mean_mix_probs_mtx[-sample_size:, :].mean(axis=0)
mean_alpha_ = mean_alpha_mtx[-sample_size:, :].mean(axis=0)
mean_loc_ = mean_loc_mtx[-sample_size:, :].mean(axis=0)
mean_precision_ = mean_precision_mtx[-sample_size:, :].mean(axis=0)
Elapsed time: 309.8013095855713 seconds

4. تصور النتيجة

4.1 نتيجة مجمعة

أولاً ، نتخيل نتيجة التجميع.

لتعيين كل عينة \(x_i\) إلى مجموعة \(j\)، نحسب الخلفي من \(z_i\) على النحو التالي:

\[\begin{align*} j = \underset{z_i}{\arg\max}\,p(z_i\,|\,x_i,\,\boldsymbol{\theta}) \end{align*}\]

loc_for_posterior = tf.compat.v1.placeholder(
    dtype, [None, max_cluster_num, dims], name='loc_for_posterior')
precision_for_posterior = tf.compat.v1.placeholder(
    dtype, [None, max_cluster_num, dims], name='precision_for_posterior')
mix_probs_for_posterior = tf.compat.v1.placeholder(
    dtype, [None, max_cluster_num], name='mix_probs_for_posterior')

# Posterior of z (unnormalized)
unnomarlized_posterior = tfd.MultivariateNormalDiag(
    loc=loc_for_posterior, scale_diag=precision_for_posterior)\
   .log_prob(tf.expand_dims(tf.expand_dims(observations, axis=1), axis=1))\
   + tf.log(mix_probs_for_posterior[tf.newaxis, ...])

# Posterior of z (normarizad over latent states)
posterior = unnomarlized_posterior\
  - tf.reduce_logsumexp(unnomarlized_posterior, axis=-1)[..., tf.newaxis]

cluster_asgmt = sess.run(tf.argmax(
    tf.reduce_mean(posterior, axis=1), axis=1), feed_dict={
        loc_for_posterior: mean_loc_mtx[-sample_size:, :],
        precision_for_posterior: mean_precision_mtx[-sample_size:, :],
        mix_probs_for_posterior: mean_mix_probs_mtx[-sample_size:, :]})

idxs, count = np.unique(cluster_asgmt, return_counts=True)

print('Number of inferred clusters = {}\n'.format(len(count)))
np.set_printoptions(formatter={'float': '{: 0.3f}'.format})

print('Number of elements in each cluster = {}\n'.format(count))

def convert_int_elements_to_consecutive_numbers_in(array):
  unique_int_elements = np.unique(array)
  for consecutive_number, unique_int_element in enumerate(unique_int_elements):
    array[array == unique_int_element] = consecutive_number
  return array

cmap = plt.get_cmap('tab10')
plt.scatter(
    observations[:, 0], observations[:, 1],
    1,
    c=cmap(convert_int_elements_to_consecutive_numbers_in(cluster_asgmt)))
plt.axis([-10, 10, -10, 10])
plt.show()
Number of inferred clusters = 3

Number of elements in each cluster = [16911 16645 16444]

بي إن جي

يمكننا أن نرى عددًا متساويًا تقريبًا من العينات يتم تخصيصها للمجموعات المناسبة وقد نجح النموذج في استنتاج العدد الصحيح من المجموعات أيضًا.

4.2 تصور عدم اليقين

هنا ، ننظر إلى عدم اليقين في نتيجة التجميع من خلال تصورها لكل عينة.

نحسب عدم اليقين باستخدام الانتروبيا:

\[\begin{align*} \text{Uncertainty}_\text{entropy} = -\frac{1}{K}\sum^{K}_{z_i=1}\sum^{O}_{l=1}p(z_i\,|\,x_i,\,\boldsymbol{\theta}_l)\log p(z_i\,|\,x_i,\,\boldsymbol{\theta}_l) \end{align*}\]

في pSGLD ، نتعامل مع قيمة معلمة التدريب في كل تكرار كعينة من التوزيع اللاحق لها. وهكذا، نحسب الكون على القيم من \(O\) التكرار لكل معلمة. يتم حساب قيمة الانتروبيا النهائية عن طريق حساب متوسط ​​الانتروبيا لجميع تخصيصات الكتلة.

# Calculate entropy
posterior_in_exponential = tf.exp(posterior)
uncertainty_in_entropy = tf.reduce_mean(-tf.reduce_sum(
    posterior_in_exponential
    * posterior,
    axis=1), axis=1)

uncertainty_in_entropy_ = sess.run(uncertainty_in_entropy, feed_dict={
    loc_for_posterior: mean_loc_mtx[-sample_size:, :],
    precision_for_posterior: mean_precision_mtx[-sample_size:, :],
    mix_probs_for_posterior: mean_mix_probs_mtx[-sample_size:, :]
})
plt.title('Entropy')
sc = plt.scatter(observations[:, 0],
                 observations[:, 1],
                 1,
                 c=uncertainty_in_entropy_,
                 cmap=plt.cm.viridis_r)
cbar = plt.colorbar(sc,
                    fraction=0.046,
                    pad=0.04,
                    ticks=[uncertainty_in_entropy_.min(),
                           uncertainty_in_entropy_.max()])
cbar.ax.set_yticklabels(['low', 'high'])
cbar.set_label('Uncertainty', rotation=270)
plt.show()

بي إن جي

في الرسم البياني أعلاه ، يمثل الإضاءة الأقل مزيدًا من عدم اليقين. يمكننا أن نرى العينات القريبة من حدود المجموعات لديها قدر أكبر من عدم اليقين بشكل خاص. هذا صحيح بشكل حدسي ، أن تلك العينات يصعب تجميعها.

4.3 يعني وحجم مكون الخليط المختار

المقبل، ونحن ننظر إلى مجموعات المختارة \(\mu_j\) و \(\sigma_j\).

for idx, numbe_of_samples in zip(idxs, count):
  print(
      'Component id = {}, Number of elements = {}'
      .format(idx, numbe_of_samples))
  print(
      'Mean loc = {}, Mean scale = {}\n'
      .format(mean_loc_[idx, :], mean_precision_[idx, :]))
Component id = 0, Number of elements = 16911
Mean loc = [-4.030 -4.113], Mean scale = [ 0.994  0.972]

Component id = 4, Number of elements = 16645
Mean loc = [ 3.999  4.069], Mean scale = [ 1.038  1.046]

Component id = 5, Number of elements = 16444
Mean loc = [-0.005 -0.023], Mean scale = [ 0.967  1.025]

مرة أخرى، \(\boldsymbol{\mu_j}\) و \(\boldsymbol{\sigma_j}\) على مقربة من الحقيقة على الارض.

4.4 وزن الخليط لكل مكون من مكونات الخليط

نحن ننظر أيضًا إلى أوزان الخليط المستنتج.

plt.ylabel('Mean posterior of mixture weight')
plt.xlabel('Component')
plt.bar(range(0, max_cluster_num), mean_mix_probs_)
plt.show()

بي إن جي

نرى فقط عددًا قليلاً (ثلاثة) من مكونات الخليط لها أوزان كبيرة وبقية الأوزان لها قيم قريبة من الصفر. يوضح هذا أيضًا أن النموذج نجح في استنتاج العدد الصحيح لمكونات الخليط الذي يشكل توزيع العينات.

4.5 تقارب \(\alpha\)

نحن ننظر إلى التقارب بين المعلمة تركيز توزيع ديريتشليت في \(\alpha\).

print('Value of inferred alpha = {0:.3f}\n'.format(mean_alpha_[0]))
plt.ylabel('Sample value of alpha')
plt.xlabel('Iteration')
plt.plot(mean_alpha_mtx)
plt.show()
Value of inferred alpha = 0.679

بي إن جي

وبالنظر إلى حقيقة أن أصغر \(\alpha\) النتائج في عدد أقل من المتوقع من التجمعات في نموذج خليط ديريتشليت، ونموذج يبدو أن تعلم العدد الأمثل للمجموعات خلال التكرار.

4.6 العدد المستنتج من الكتل على التكرارات

نحن نتخيل كيف يتغير العدد المستنتج من المجموعات عبر التكرارات.

للقيام بذلك ، نستنتج عدد الكتل على التكرارات.

step = sample_size
num_of_iterations = 50
estimated_num_of_clusters = []
interval = (training_steps - step) // (num_of_iterations - 1)
iterations = np.asarray(range(step, training_steps+1, interval))
for iteration in iterations:
  start_position = iteration-step
  end_position = iteration

  result = sess.run(tf.argmax(
      tf.reduce_mean(posterior, axis=1), axis=1), feed_dict={
          loc_for_posterior:
              mean_loc_mtx[start_position:end_position, :],
          precision_for_posterior:
              mean_precision_mtx[start_position:end_position, :],
          mix_probs_for_posterior:
              mean_mix_probs_mtx[start_position:end_position, :]})

  idxs, count = np.unique(result, return_counts=True)
  estimated_num_of_clusters.append(len(count))
plt.ylabel('Number of inferred clusters')
plt.xlabel('Iteration')
plt.yticks(np.arange(1, max(estimated_num_of_clusters) + 1, 1))
plt.plot(iterations - 1, estimated_num_of_clusters)
plt.show()

بي إن جي

خلال التكرارات ، يقترب عدد الكتل من ثلاثة. ونتيجة لتقارب \(\alpha\) إلى قيمة أقل على التكرار، يمكننا أن نرى نموذج وبنجاح تعلم المعلمات لاستنتاج العدد الأمثل من المجموعات.

ومن المثير للاهتمام، يمكننا أن نرى الاستدلال وقد تقاربت بالفعل إلى الرقم الصحيح للمجموعات في التكرار في وقت مبكر، على عكس \(\alpha\) المتقاربة في الكثير من التكرار في وقت لاحق.

4.7 تركيب النموذج باستخدام RMSProp

في هذا القسم ، لمعرفة فعالية مخطط أخذ عينات مونت كارلو من pSGLD ، نستخدم RMSProp لملاءمة النموذج. اخترنا RMSProp للمقارنة لأنه يأتي بدون مخطط أخذ العينات ويعتمد pSGLD على RMSProp.

# Learning rates and decay
starter_learning_rate_rmsprop = 1e-2
end_learning_rate_rmsprop = 1e-4
decay_steps_rmsprop = 1e4

# Number of training steps
training_steps_rmsprop = 50000

# Mini-batch size
batch_size_rmsprop = 20
# Define trainable variables.
mix_probs_rmsprop = tf.nn.softmax(
    tf.Variable(
        name='mix_probs_rmsprop',
        initial_value=np.ones([max_cluster_num], dtype) / max_cluster_num))

loc_rmsprop = tf.Variable(
    name='loc_rmsprop',
    initial_value=np.zeros([max_cluster_num, dims], dtype)
    + np.random.uniform(
        low=-9, #set around minimum value of sample value
        high=9, #set around maximum value of sample value
        size=[max_cluster_num, dims]))

precision_rmsprop = tf.nn.softplus(tf.Variable(
    name='precision_rmsprop',
    initial_value=
    np.ones([max_cluster_num, dims], dtype=dtype)))

alpha_rmsprop = tf.nn.softplus(tf.Variable(
    name='alpha_rmsprop',
    initial_value=
    np.ones([1], dtype=dtype)))

training_vals_rmsprop =\
    [mix_probs_rmsprop, alpha_rmsprop, loc_rmsprop, precision_rmsprop]

# Prior distributions of the training variables

#Use symmetric Dirichlet prior as finite approximation of Dirichlet process.
rv_symmetric_dirichlet_process_rmsprop = tfd.Dirichlet(
    concentration=np.ones(max_cluster_num, dtype)
    * alpha_rmsprop / max_cluster_num,
    name='rv_sdp_rmsprop')

rv_loc_rmsprop = tfd.Independent(
    tfd.Normal(
        loc=tf.zeros([max_cluster_num, dims], dtype=dtype),
        scale=tf.ones([max_cluster_num, dims], dtype=dtype)),
    reinterpreted_batch_ndims=1,
    name='rv_loc_rmsprop')


rv_precision_rmsprop = tfd.Independent(
    tfd.InverseGamma(
        concentration=np.ones([max_cluster_num, dims], dtype),
        rate=np.ones([max_cluster_num, dims], dtype)),
    reinterpreted_batch_ndims=1,
    name='rv_precision_rmsprop')

rv_alpha_rmsprop = tfd.InverseGamma(
    concentration=np.ones([1], dtype=dtype),
    rate=np.ones([1]),
    name='rv_alpha_rmsprop')

# Define mixture model
rv_observations_rmsprop = tfd.MixtureSameFamily(
    mixture_distribution=tfd.Categorical(probs=mix_probs_rmsprop),
    components_distribution=tfd.MultivariateNormalDiag(
        loc=loc_rmsprop,
        scale_diag=precision_rmsprop))
og_prob_parts_rmsprop = [
    rv_loc_rmsprop.log_prob(loc_rmsprop),
    rv_precision_rmsprop.log_prob(precision_rmsprop),
    rv_alpha_rmsprop.log_prob(alpha_rmsprop),
    rv_symmetric_dirichlet_process_rmsprop
        .log_prob(mix_probs_rmsprop)[..., tf.newaxis],
    rv_observations_rmsprop.log_prob(observations_tensor)
    * num_samples / batch_size
]
joint_log_prob_rmsprop = tf.reduce_sum(
    tf.concat(log_prob_parts_rmsprop, axis=-1), axis=-1)
# Define learning rate scheduling
global_step_rmsprop = tf.Variable(0, trainable=False)
learning_rate = tf.train.polynomial_decay(
    starter_learning_rate_rmsprop,
    global_step_rmsprop, decay_steps_rmsprop,
    end_learning_rate_rmsprop, power=1.)

# Set up the optimizer. Don't forget to set data_size=num_samples.
optimizer_kernel_rmsprop = tf.train.RMSPropOptimizer(
    learning_rate=learning_rate,
    decay=0.99)

train_op_rmsprop = optimizer_kernel_rmsprop.minimize(-joint_log_prob_rmsprop)

init_rmsprop = tf.global_variables_initializer()
sess.run(init_rmsprop)

start = time.time()
for it in range(training_steps_rmsprop):
  [
      _
  ] = sess.run([
      train_op_rmsprop
  ], feed_dict={
      observations_tensor: sess.run(next_batch)})

elapsed_time_rmsprop = time.time() - start
print("RMSProp elapsed_time: {} seconds ({} iterations)"
      .format(elapsed_time_rmsprop, training_steps_rmsprop))
print("pSGLD elapsed_time: {} seconds ({} iterations)"
      .format(elapsed_time_psgld, training_steps))

mix_probs_rmsprop_, alpha_rmsprop_, loc_rmsprop_, precision_rmsprop_ =\
  sess.run(training_vals_rmsprop)
RMSProp elapsed_time: 53.7574200630188 seconds (50000 iterations)
pSGLD elapsed_time: 309.8013095855713 seconds (10000 iterations)

قارن بـ pSGLD ، على الرغم من أن عدد التكرارات لـ RMSProp أطول ، فإن التحسين بواسطة RMSProp يكون أسرع بكثير.

بعد ذلك ، ننظر إلى نتيجة التجميع.

cluster_asgmt_rmsprop = sess.run(tf.argmax(
    tf.reduce_mean(posterior, axis=1), axis=1), feed_dict={
        loc_for_posterior: loc_rmsprop_[tf.newaxis, :],
        precision_for_posterior: precision_rmsprop_[tf.newaxis, :],
        mix_probs_for_posterior: mix_probs_rmsprop_[tf.newaxis, :]})

idxs, count = np.unique(cluster_asgmt_rmsprop, return_counts=True)

print('Number of inferred clusters = {}\n'.format(len(count)))
np.set_printoptions(formatter={'float': '{: 0.3f}'.format})

print('Number of elements in each cluster = {}\n'.format(count))

cmap = plt.get_cmap('tab10')
plt.scatter(
    observations[:, 0], observations[:, 1],
    1,
    c=cmap(convert_int_elements_to_consecutive_numbers_in(
        cluster_asgmt_rmsprop)))
plt.axis([-10, 10, -10, 10])
plt.show()
Number of inferred clusters = 4

Number of elements in each cluster = [ 1644 15267 16647 16442]

بي إن جي

لم يتم الاستدلال على عدد المجموعات بشكل صحيح عن طريق تحسين RMSProp في تجربتنا. نحن ننظر أيضا إلى وزن الخليط.

plt.ylabel('MAP inferece of mixture weight')
plt.xlabel('Component')
plt.bar(range(0, max_cluster_num), mix_probs_rmsprop_)
plt.show()

بي إن جي

يمكننا أن نرى أن العدد غير الصحيح للمكونات لها أوزان خليط كبيرة.

على الرغم من أن التحسين يستغرق وقتًا أطول ، إلا أن pSGLD ، الذي يحتوي على مخطط أخذ عينات مونت كارلو ، كان أداءه أفضل في تجربتنا.

5. الخلاصة

في هذا الكمبيوتر الدفتري ، وصفنا كيفية تجميع عدد كبير من العينات بالإضافة إلى استنتاج عدد المجموعات في وقت واحد من خلال تركيب مزيج عملية Dirichlet لتوزيع Gaussian باستخدام pSGLD.

أظهرت التجربة أن النموذج قد جمع العينات بنجاح واستنتج العدد الصحيح من المجموعات. أيضًا ، أظهرنا أن مخطط أخذ عينات مونت كارلو من pSGLD يسمح لنا بتصور عدم اليقين في النتيجة. ليس فقط تجميع العينات ولكن أيضًا رأينا أن النموذج يمكن أن يستنتج المعلمات الصحيحة لمكونات الخليط. فيما يتعلق بالعلاقة بين المعلمات وعدد الكتل المستنتجة ، قمنا بالتحقيق في كيفية تعلم النموذج للمعلمة للتحكم في عدد المجموعات الفعالة من خلال تصور الارتباط بين تقارب 𝛼 وعدد المجموعات المستنتجة. أخيرًا ، لقد نظرنا في نتائج ملاءمة النموذج باستخدام RMSProp. لقد رأينا RMSProp ، وهو المُحسِّن بدون مخطط أخذ عينات مونت كارلو ، يعمل بشكل أسرع بكثير من pSGLD ولكنه ينتج دقة أقل في التجميع.

على الرغم من أن مجموعة بيانات اللعبة لا تحتوي إلا على 50000 عينة ذات بعدين فقط ، إلا أن تحسين أسلوب الدُفعة المصغرة المستخدم هنا قابل للتطوير لمجموعات بيانات أكبر بكثير.