【问题标题】:How to customize a Deep Learning model if the output is one-hot vectors? [closed]如果输出是 one-hot 向量,如何自定义深度学习模型? [关闭]
【发布时间】:2019-08-30 09:33:26
【问题描述】:

我正在尝试使用 TensorFlow 和 Keras 构建深度学习模型。这是单例多标签任务的顺序模型,是Multi-Instance Multi-Label的简化版。

具体来说,我的模型的输入是一个固定长度的数组,所以可以这样表示为一个向量:

我的模型的输出是一个字母序列,它们来自一个固定大小的字母表。例如,{A,B,C,D} 的字母表只有 4 个可能的成员。所以我可以使用 one-hot 向量来表示序列中的每个字母。

序列的长度是可变的,但为了简单起见,我使用固定长度(等于最长序列的长度)来存储所有序列。

如果序列的长度小于固定长度,则该序列由 one-hot 向量(等于序列的实际长度)和零向量(等于剩余长度)表示。例如,CADB 用 4 * 5 矩阵表示,如下所示:

请注意:这个矩阵的前 4 列是 one-hot 向量,每个向量都有一个且只有一个 1 条目,其他所有条目都是 0。 但是最后一列的条目都是0,可以看作是补零,因为字母序列不够长。

所以一句话,输入是一个向量,输出是一个矩阵。

与上面发布的链接不同,输出矩阵应该被视为一个整体。因此,一个输入向量被分配给整个矩阵,而不是该矩阵的一行或一列。

我的问题是:如何为这个特殊的输出定制我的深度学习模型,例如:

  1. 我应该选择或设计什么损失函数和准确度指标?
  2. 我是否需要在模型的最后自定义一个特殊层?

【问题讨论】:

  • 是什么让您认为这是一种不常见的情况?事实上,这可能是最常见的情况之一,并且有很多例子。简而言之:您需要在输出层激活softmax,并将categorical_crossentropy 作为损失函数。
  • 嗨 sebrockm,非常感谢您的专业回复。实际上,我已经尝试训练我的模型,并通过测试数据集获得了很好的预测性能(损失接近 0,准确率超过 0.9)。但是当我输出结果时,我发现标签的预测完全不同。显然,结果很糟糕,尽管损失和准确率看起来很不错。这让我觉得我的模型与传统模型不同,也许我应该为我的模型使用一些新设计。
  • 那么您对数据的解释有问题。如此好的损失和准确性不会导致完全不同的标签除非您对数据的解释不正确。例如,确保不要混淆列和行的角色。您发布的链接说,一个实例可以有多个标签分配给它。这与您对单热向量的描述相矛盾。那么,也许不是一列,而是矩阵的一行对实例的标签进行编码?
  • 我上面贴的链接是一篇关于多实例多标签任务的论文。但是我的模型是针对单实例多标签任务的,比较简单。在我的模型中,一个实例(一个输入向量)被分配给整个矩阵,而不仅仅是一列或一行。实际上,输出是一个整体,但它只能用一组 one-hot 向量表示,因为它是一个字母序列(看起来像一组标签)。
  • 好的,我知道了。您也许应该稍微改一下您的问题以更清楚地指出这一点。我会提交答案。

标签: tensorflow keras deep-learning


【解决方案1】:

您应该在输出层使用softmax 激活函数,并将categorical_crossentropy 作为损失函数。

但是,正如您在上面的链接中看到的,问题是这两个函数默认应用于最后一个轴 (axis=-1),而在您的情况下,它是倒数第二个轴(矩阵)是单热编码的。

要使用右轴,一种选择是定义您自己的这些函数版本,如下所示:

def softmax_columns(x):
    return tf.keras.backend.softmax(x, axis=-2)

def categorical_crossentropy_columns(target, output):
    return tf.keras.backend.categorical_crossentropy(target, output, axis=-2)

然后,您可以像这样使用它们:

model.add(SomeLayer(..., activation=softmax_columns, ...)) # output layer

model.compile(loss=categorical_crossentropy_columns, ...)

一个不错的选择(通常,不仅在这里)是在categorical_crossentropy 调用中使用from_logits=True。这有效地使 softmax 内置到损失函数中,因此您的模型本身不再需要(实际上:必须没有)最终的 softmax 激活。这不仅节省了工作量,而且在数值上也更加稳定。

【讨论】:

  • 在 Keras 中,维度由 (None, Row, Column, Channel) 指定。那么axis=-1是指通道轴吗?
  • @BioCoder Keras 作为一个框架,没有“指定维度”之类的东西。某些层具有指定的输入和输出形状。特别是,Conv2D 层的输入和输出形状是(None, Row, Column, Channels)。因此,对于这些层,axis=-1 确实指的是通道。你没有提到任何关于你的模型的层,所以我不能说什么。我唯一确定的事情(根据您的描述)是您的最后一层的输出形状应为(None, 4, 5),因此axis=-2 指的是列(长度为4)。
  • 是的,你说得对,输出形状是 (None, 4, 5)。我用更详细的描述和更多图表重新表述了我的问题。现在我相信你可以更清楚我的模型了。
  • @BioCoder 我已经阅读了更新,并在我的回答中解决了这个问题。是否还有任何问题或我的回答对您不起作用?
  • 我按照您的建议修改了我的代码。现在准确率下降到 0.1 以下,预测仍然很糟糕。我认为这是有道理的,因为准确性与现在的预测一致。所以也许问题确实部分在于损失函数和轴的选择。也许我的模型的结构需要改进才能获得更好的性能。不过不管怎样,你的回答真的很励志,谢谢!
猜你喜欢
  • 1970-01-01
  • 2019-05-04
  • 2019-11-30
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 2022-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多