我正在使用tf.keras.utils.to_categorical()
进行数据准备。我有一个非常简单的列表,我想从中得到分类值。所以我这样做:
tf.keras.utils.to_categorical([1,2,3], num_classes=6)
我得到:
array([[0., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0.],
[0., 0., 0., 1., 0., 0.]], dtype=float32)
现在,为了进一步使用,我将发送给函数的值减少1,以获得6个类,而不使用0作为占位符:
tf.keras.utils.to_categorical([x -1 for x in [1,2,3]], num_classes=6)
结果是:
array([[1., 0., 0., 0., 0., 0.],
[0., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0.]], dtype=float32)
现在是奇怪的部分。我想将某些功能设置为0,这就是我发现这种行为的原因:
tf.keras.utils.to_categorical([x -1 for x in [-4,2,3]], num_classes=6)
结果在:
array([[0., 1., 0., 0., 0., 0.],
[0., 1., 0., 0., 0., 0.],
[0., 0., 1., 0., 0., 0.]], dtype=float32)
所以to_categorical()
将-4和2混合到同一个类中,我觉得这很奇怪。我本以为会出现异常,因为列表无法映射到6个类。但我没想到会发生这种事。这是一个bug还是一个功能,为什么会发生这种情况?
谢谢!
这完全正常。它只是与Python的负索引保持一致。参见:
import tensorflow as tf
tf.keras.utils.to_categorical([0, 1, 2, -1, -2, -3])
array([[1., 0., 0.],
[0., 1., 0.],
[0., 0., 1.],
[0., 0., 1.],
[0., 1., 0.],
[1., 0., 0.]], dtype=float32)
换句话说:
import tensorflow as tf
a = tf.keras.utils.to_categorical([0, 1, 2], num_classes=3)
b = tf.keras.utils.to_categorical([-3, -2, -1], num_classes=3)
print(a)
print(b)
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]
如果你想知道为什么会发生这种情况,我认为keras中的to_categorical不适用于负数。但如果你想解决它,我建议让所有的数字都大于0。这个代码是这样做的:
arr=numpy.array([-5,-4,-2,-1,0,1,2,3,4]) #anything
arr+=(0-arr.min())
Keras to_categorical不适用于负数。上面写得很清楚,数字必须从0开始。
https://keras.io/api/utils/python_utils/#to_categorical-功能
如果你仍然需要让它发挥作用,制作一本字典来映射负数。