【问题标题】:memory issues when transforming np.array using to_categorical使用 to_categorical 转换 np.array 时的内存问题
【发布时间】:2019-01-24 05:31:51
【问题描述】:

我有一个这样的 numpy 数组:

[[0. 1. 1. ... 0. 0. 1.]
 [0. 0. 0. ... 0. 0. 1.]
 [0. 0. 1. ... 0. 0. 0.]
 ...
 [0. 0. 0. ... 0. 0. 1.]
 [0. 0. 0. ... 0. 0. 1.]
 [0. 0. 0. ... 1. 0. 1.]]

我这样改造它以减少内存需求:

x_val = x_val.astype(np.int)

导致:

[[0 1 1 ... 0 0 1]
 [0 0 0 ... 0 0 1]
 [0 0 1 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 1]
 [0 0 0 ... 0 0 1]
 [0 0 0 ... 1 0 1]]

但是,当我这样做时:

x_val = to_categorical(x_val)

我明白了:

in to_categorical
    categorical = np.zeros((n, num_classes), dtype=np.float32)
MemoryError

任何想法为什么?最终,numpy 数组包含二进制分类问题的标签。到目前为止,我已经将它用作float32,就像在 Keras ANN 中一样,它运行良好,并且我取得了相当不错的性能。那么真的有必要运行to_categorical吗?

【问题讨论】:

  • 如果是二分类问题,标签应该是零和一;但是你的标签对我来说似乎很奇怪!例如,第一行,即[0. 1. 1. ... 0. 0. 1.],在解释为标签时对应于什么?如果要执行二进制分类,标签的形状应为(n_samples,)。我猜你正在做多标签分类,即每个样本可能有多个标签。在这种情况下,标签是正确的,您根本不需要使用to_categorical
  • 你想用 to_categorical 实现什么?对我来说,这里看起来错位了。
  • @today 抱歉,我可能在这里遗漏了一些东西,但不是 0. = 0 => Class1 和 1. = 1 > Class2。后一类有待预测...
  • @Digital-Thinking 不确定我理解。它是否像在多类问题中那样放错地方了,我会使用 categorical_crossentropy 作为损失函数,而在二元分类问题中我使用 binary_crossentropy(就像我目前所做的那样)?因此 to_categorical 对她没有意义,因为这是二进制的?
  • to_categorical 如果您有 multicalss 标签,它确实有意义,这些标签存储在一个单一的值中。如果你有像 (0,1,2,3,n) 这样的类,它们会被单热编码,并且你会得到每个不同值的维度(每个值的 n 维数组)。

标签: python numpy machine-learning keras classification


【解决方案1】:

你不需要使用to_categorical,因为我猜你正在做多标签分类。为了一劳永逸地避免任何混淆(!),让我解释一下。

如果你在做二元分类,这意味着每个样本可能只属于一个 两个类,例如猫 vs 狗或快乐 vs 悲伤或正面评价 vs 负面评价,然后:

  • 标签应类似于[0 1 0 0 1 ... 0],形状为(n_samples,),即每个样本都有一个(例如猫)或零(例如狗)标签。
  • 用于最后一层的激活函数通常是sigmoid(或任何其他输出值在 [0,1] 范围内的函数)。
  • 通常使用的损失函数是binary_crossentropy

如果您正在进行多类分类,这意味着每个样本可能只属于许多类中的一个,例如猫 vs 狗 vs 狮子或快乐 vs 中性 vs 悲伤或正面评价 vs 中性评价 vs 负面评价,然后:

  • 标签应该是one-hot编码,即[1, 0, 0]对应于猫,[0, 1, 0]对应于狗,[0, 0, 1]对应于狮子,在这种情况下,标签的形状为(n_samples, n_classes);或者它们可以是整数(即稀疏标签),即 1 代表猫,2 代表狗,3 代表狮子,在这种情况下,标签的形状为 (n_samples,)to_categorical 函数用于将稀疏标签转换为 one-hot 编码标签,当然如果您愿意的话。
  • 使用的激活函数通常是softmax
  • 使用的损失函数取决于标签的格式:如果它们是 one-hot 编码的,则使用 categorical_crossentropy,如果它们是稀疏的,则使用 sparse_categorical_crossentropy

如果您正在进行多标签分类,这意味着每个样本可能属于零个、一个或多个类,例如一张图片可能同时包含猫和狗,那么:

  • 标签应该类似于[[1 0 0 1 ... 0], ..., [0 0 1 0 ... 1]],形状为(n_samples, n_classes)。例如,标签[1 1] 表示对应的样本属于两个类(例如猫和狗)。
  • 使用的激活函数是sigmoid,因为大概每个类都独立于另一个类。
  • 使用的损失函数是binary_crossentropy

【讨论】:

  • 惊人的总结!顺便说一句,当我将 x_val = x_val.astype(np.uint8) 应用于我的二进制分类问题的训练标签时,测试数据上的 AUC 要低得多......因此将标签从浮点数转换为整数会导致问题!
  • @cs0815 您不需要转换为 int。我猜这个问题是由于在神经网络中你正在处理浮点值。甚至二元分类方法的输出也是一个介于零和一之间的浮点值,对应于属于正类的概率。因此,计算损失或梯度等内部计算可能会受到这种转换的影响。通常所有值都必须是浮点数,除非另有要求(比如嵌入层的输入应该是整数)。
【解决方案2】:

忽略在我的场景中应用 to_categorical 毫无意义的事实。以下解决了内存问题:

x_val = x_val.astype(np.uint8)

【讨论】:

    猜你喜欢
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-22
    • 1970-01-01
    • 1970-01-01
    • 2021-01-04
    • 2018-12-20
    相关资源
    最近更新 更多