繁体   English   中英

为什么 GPflow model 似乎无法使用 TensorFlow 优化器(例如 tf.optimizers.Adam)学习任何东西?

[英]Why does a GPflow model not seem to learn anything with TensorFlow optimizers such as tf.optimizers.Adam?

我的诱导点设置为可训练,但在我调用opt.minimize()时不会改变。 为什么会这样,这意味着什么? 这是否意味着 model 没有学习? tf.optimizers.Adam(lr)gpflow.optimizers.Scipy什么区别?

以下是根据文档改编的简单分类示例。 当我使用 gpflow 的 Scipy 优化器运行此代码示例时,我得到了经过训练的结果,并且诱导变量的值不断变化。 但是当我使用 Adam 优化器时,我只能得到一条直线预测,并且诱导点的值保持不变。 它表明 model 没有使用 Adam 优化器进行学习。

训练前数据plot

使用 Adam 训练后的数据为 plot

使用 gpflow 优化器训练后的数据 plot Scipy

该示例的链接是https://gpflow.readthedocs.io/en/develop/notebooks/advanced/multiclass_classification.html

import numpy as np
import tensorflow as tf


import warnings
warnings.filterwarnings('ignore')  # ignore DeprecationWarnings from tensorflow

import matplotlib.pyplot as plt

import gpflow

from gpflow.utilities import print_summary, set_trainable
from gpflow.ci_utils import ci_niter

from tensorflow2_work.multiclass_classification import plot_posterior_predictions, colors

np.random.seed(0)  # reproducibility

# Number of functions and number of data points
C = 3
N = 100

# RBF kernel lengthscale
lengthscale = 0.1

# Jitter
jitter_eye = np.eye(N) * 1e-6

# Input
X = np.random.rand(N, 1)

kernel_se = gpflow.kernels.SquaredExponential(lengthscale=lengthscale)
K = kernel_se(X) + jitter_eye

# Latents prior sample
f = np.random.multivariate_normal(mean=np.zeros(N), cov=K, size=(C)).T

# Hard max observation
Y = np.argmax(f, 1).reshape(-1,).astype(int)
print(Y.shape)

# One-hot encoding
Y_hot = np.zeros((N, C), dtype=bool)
Y_hot[np.arange(N), Y] = 1

data = (X, Y)

plt.figure(figsize=(12, 6))
order = np.argsort(X.reshape(-1,))
print(order.shape)

for c in range(C):
    plt.plot(X[order], f[order, c], '.', color=colors[c], label=str(c))
    plt.plot(X[order], Y_hot[order, c], '-', color=colors[c])


plt.legend()
plt.xlabel('$X$')
plt.ylabel('Latent (dots) and one-hot labels (lines)')
plt.title('Sample from the joint $p(Y, \mathbf{f})$')
plt.grid()
plt.show()


# sum kernel: Matern32 + White
kernel = gpflow.kernels.Matern32() + gpflow.kernels.White(variance=0.01)

# Robustmax Multiclass Likelihood
invlink = gpflow.likelihoods.RobustMax(C)  # Robustmax inverse link function
likelihood = gpflow.likelihoods.MultiClass(C, invlink=invlink)  # Multiclass likelihood
Z = X[::5].copy()  # inducing inputs
#print(Z)

m = gpflow.models.SVGP(kernel=kernel, likelihood=likelihood,
    inducing_variable=Z, num_latent_gps=C, whiten=True, q_diag=True)

# Only train the variational parameters
set_trainable(m.kernel.kernels[1].variance, True)
set_trainable(m.inducing_variable, True)
print(m.inducing_variable.Z)
print_summary(m)


training_loss = m.training_loss_closure(data) 

opt.minimize(training_loss, m.trainable_variables)
print(m.inducing_variable.Z)
print_summary(m.inducing_variable.Z)


print(m.inducing_variable.Z)

# %%
plot_posterior_predictions(m, X, Y)

问题中给出的示例不可复制和粘贴,但您似乎只是将opt = gpflow.optimizers.Scipy()opt = tf.optimizers.Adam()交换。 gpflow 的 Scipy 优化器的minimize()方法运行一次scipy.optimize.minimize调用,它默认运行到收敛(您也可以通过将options=dict(maxiter=100)传递给最小化()调用)。

相比之下,TensorFlow 优化器的minimize()方法只运行一个优化步骤。 要运行更多步骤,比如iter = 100 ,您需要手动编写一个循环:

for _ in range(iter):
    opt.minimize(model.training_loss, model.trainable_variables)

为了使其真正运行得更快,您还需要将优化步骤包装在tf.function

@tf.function
def optimization_step():
    opt.minimize(model.training_loss, model.trainable_variables)

for _ in range(iter):
    optimization_step()

这运行完全iter步骤 - 在 TensorFlow 中你必须自己处理收敛检查,你的 model 在这么多步骤之后可能会或可能不会收敛。

所以在您的使用中,您只运行了一个步骤——这确实改变了参数,但可能太少而无法注意到差异。 (通过提高学习率,您可以在一步中看到更大的效果,尽管这对于通过许多步骤实际优化 model 并不是一个好主意。)

随机变分推理笔记本中演示了 Adam 优化器与 GPflow 模型的用法,尽管它也适用于非随机优化。

请注意,在任何情况下,所有参数(例如诱导点位置)默认设置为可训练,因此您对set_trainable(..., True)的调用不会影响此处发生的事情。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM