簡體   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