如何建立神经网络来输出序数数据?

机器算法验证 神经网络 序数数据 软最大
2022-02-05 22:05:55

我有一个神经网络来预测输出变量是序数的东西。我将在下面使用三个可能的输出 A < B < C 来描述。

如何使用神经网络输出分类数据非常明显:输出只是最后(通常是全连接)层的 softmax,每个类别一个,预测的类别是具有最大输出值的类别(这是许多流行模型中的默认值)。我一直在对序数值使用相同的设置。但是,在这种情况下,输出通常没有意义,例如 A 和 C 的网络输出高但 B 低:这对于序数值来说是不合理的。

我对此有一个想法,即通过将输出与 A 的 1 0 0、B 的 1 1 0 和 C 的 1 1 1 进行比较来计算损失。稍后可以使用另一个分类器(例如贝叶斯)调整确切的阈值) 但这似乎抓住了输入排序的基本思想,而没有规定任何特定的区间尺度。

解决这个问题的标准方法是什么?是否有任何研究或参考资料描述了不同方法的优缺点?

2个回答

我相信大多数人所做的只是将序数分类视为通用的多类分类。因此,如果他们有个类别,他们将有个输出,并且简单地使用交叉熵作为损失。KK

但是有些人已经设法为您的序数类发明了一种巧妙的编码(参见这个stackoverflow 答案)。这是一种单热编码,

  • 第 1 类表示为 [0 0 0 0 ...]

  • 第 2 类表示为 [1 0 0 0 ...]

  • 第 3 类表示为 [1 1 0 0 ...]

即每个神经元都在预测概率你仍然必须使用 sigmoid 作为激活函数,但我认为这有助于网络理解类之间的一些连续性,我不知道。之后,您进行后处理 ( ) 以将二进制输出转换为您的类。P(y^<k)np.sum

这种策略类似于Frank 和 Hall的合奏,我认为这是此类策略的第一次发布

我认为仅将序数标签编码为的方法

  • 第 1 类表示为 [0 0 0 0 ...]

  • 第 2 类表示为 [1 0 0 0 ...]

  • 第 3 类表示为 [1 1 0 0 ...]

并使用二元交叉熵,因为损失函数不是最优的。如评论中所述,预测向量可能是例如 [1 0 1 0 ...]。这对于进行预测是不希望的。

神经网络的秩一致序数回归一文描述了如何限制神经网络进行秩一致的预测。你必须确保最后一层共享它的权重,但应该有不同的偏差。您可以在 Tensorflow 中通过添加以下内容作为网络的最后一部分来实现这一点(学分https://stackoverflow.com/questions/59656313/how-to-share-weights-and-not-biases-in-keras-密集层):

class BiasLayer(tf.keras.layers.Layer):
    def __init__(self, units, *args, **kwargs):
        super(BiasLayer, self).__init__(*args, **kwargs)
        self.bias = self.add_weight('bias',
                                    shape=[units],
                                    initializer='zeros',
                                    trainable=True)

    def call(self, x):
        return x + self.bias


# Add the following as the output of the Sequential model
model.add(keras.layers.Dense(1, use_bias=False))
model.add(BiasLayer(4))
model.add(keras.layers.Activation("sigmoid"))

请注意,这里的序数类的数量是 5,因此是偏差。K1

我在实际数据上测试了性能差异,预测准确性大大提高。希望这可以帮助。