【问题标题】:Multi-class classification with softmax likelihood具有softmax似然的多类分类
【发布时间】:2020-12-04 00:10:36
【问题描述】:

GPflow 文档提供了一个example for multi-class classification 和robust-max 函数。我正在尝试用softmax似然训练一个多类分类器,这也是GPflow中的implemented,但我找不到任何关于如何正确使用它的文档或示例。

请在下面找到我尝试过的示例。在训练过程中,损失会平稳下降。

上面提到的robust-max 示例使用分类标签,即值0、1、2,但简单地将robust-max 替换为softmax 似然性会引发IndexError in the quadrature method。因此,我假设这个具有 softmax 似然性的模型需要 one-hot 编码标签。然而,在测试时,我注意到对于这个三类玩具示例,模型永远不会预测类 3。仔细检查后,softmax 似然性有以下method

def _log_prob(self, F, Y):
        return -tf.nn.sparse_softmax_cross_entropy_with_logits(logits=F, labels=Y[:, 0])

它看起来需要一个形状为[num_samples, 1] 的分类标签数组。

在 GP 多类分类中使用 softmax 似然的正确方法是什么?

import numpy as np
import tensorflow as tf
import gpflow
from gpflow.likelihoods.multiclass import Softmax
from tqdm.auto import tqdm


np.random.seed(0)
tf.random.set_seed(123)

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

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

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

# SquaredExponential kernel matrix
kernel_se = gpflow.kernels.SquaredExponential(lengthscales=0.1)
K = kernel_se(X) + jitter_eye

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

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

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

data = (X, Y_hot)

# sum kernel: Matern32 + White
kernel = gpflow.kernels.Matern32() + gpflow.kernels.White(variance=0.01)
likelihood = Softmax(num_classes)
m = gpflow.models.VGP(
    data=data,
    kernel=kernel,
    likelihood=likelihood,
    num_latent_gps=num_classes,
)


def run_adam(model, iterations):
    """
    Utility function running the Adam optimizer
    """

    # Create an Adam Optimizer action
    losses = []
    training_loss = model.training_loss
    optimizer = tf.optimizers.Adam()

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

    for step in tqdm(range(iterations), total=iterations):
        optimization_step()
        if step % 10 == 0:
            elbo = -training_loss().numpy()
            losses.append(elbo)
    return losses


run_adam(model=m, iterations=10000)
y_pred = m.predict_y(X)[0]
print("Training accuracy: {:3.2f}".format(np.mean(Y == np.argmax(y_pred, axis=1))))

【问题讨论】:

  • 这确实应该是 GPflow 文档示例笔记本的一部分。请问你能在 GPflow github 上打开一个documentation issue 吗?
  • 我已经打开了一个问题here

标签: python gpflow


【解决方案1】:

Softmax 使用 Monte Carlo 来估计预期的对数似然性,因此您总是需要 Adam。 RobustMax 的好处在于,对于完整的数据集,您可以使用 bfgs。我的经验是,从统计角度来看,RobustMax 并不是那么好......

我不记得标签应该以什么形式传递,RobustMaxSoftMax 之间很可能存在差异。你找到了正确的方法,我会参考tf.nn.sparse_softmax_cross_entropy_with_logits()的TensorFlow文档来确定正确的格式是什么。

【讨论】:

    猜你喜欢
    • 2019-07-20
    • 2012-08-11
    • 2019-03-08
    • 1970-01-01
    • 2014-06-22
    • 1970-01-01
    • 2020-10-25
    • 2019-06-11
    • 2019-10-13
    相关资源
    最近更新 更多