我有一个这样的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数组包含一个二分类问题的标签。到目前为止,我在Keras ANN中使用float32
格式运行得很好,并且取得了不错的性能。那么,运行to_categorical
真的有必要吗?
回答:
你不需要使用to_categorical
,因为我猜你在做多标签分类。为了避免任何混淆,让我解释一下。
如果你在做二分类,即每个样本只能属于两个类别中的一个,例如猫与狗、快乐与悲伤、正面评价与负面评价,那么:
- 标签应该像
[0 1 0 0 1 ... 0]
,形状为(n_samples,)
,即每个样本有一个标签(例如猫为1,狗为0)。 - 最后一层的激活函数通常是
sigmoid
(或任何其他输出范围在[0,1]的函数)。 - 通常使用的损失函数是
binary_crossentropy
。
如果你在做多类分类,即每个样本只能属于多个类别中的一个,例如猫与狗与狮子、快乐与中立与悲伤、正面评价与中立评价与负面评价,那么:
- 标签可以是一热编码,即
[1, 0, 0]
对应猫,[0, 1, 0]
对应狗,[0, 0, 1]
对应狮子,这种情况下标签的形状为(n_samples, n_classes)
;或者它们可以是整数(即稀疏标签),即1
对应猫,2
对应狗,3
对应狮子,这种情况下标签的形状为(n_samples,)
。to_categorical
函数用于将稀疏标签转换为一热编码标签,当然如果你希望这样做的话。 - 使用的激活函数通常是
softmax
。 - 使用的损失函数取决于标签的格式:如果它们是一热编码,则使用
categorical_crossentropy
,如果它们是稀疏的,则使用sparse_categorical_crossentropy
。
如果你在做多标签分类,即每个样本可以属于零个、一个或多个类别,例如一张图片可能同时包含猫和狗,那么:
- 标签应该像
[[1 0 0 1 ... 0], ..., [0 0 1 0 ... 1]]
,形状为(n_samples, n_classes)
。例如,标签[1 1]
表示相应的样本属于两个类别(例如猫和狗)。 - 使用的激活函数是
sigmoid
,因为假设每个类别是独立的。 - 使用的损失函数是
binary_crossentropy
。