1

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

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

训练前的数据图

与 Adam 训练后的数据图

使用 gpflow 优化器 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)
4

1 回答 1

3

问题中给出的示例不是可复制粘贴的,但您似乎只是opt = gpflow.optimizers.Scipy()opt = tf.optimizers.Adam(). minimize()gpflow 的 Scipy 优化器的方法运行一次scipy.optimize.minimize调用,默认情况下运行到收敛(您也可以通过传递来指定最大迭代次数,例如,传递options=dict(maxiter=100)给 minimize() 调用)。

相比之下,minimize()TensorFlow 优化器的方法只运行一个优化步骤。例如,要运行更多步骤,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 中,您必须自己处理收敛检查,经过这么多步骤后,您的模型可能会收敛,也可能不会收敛。

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

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

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

于 2020-05-18T07:17:42.663 回答