如何用keras处理多类分类中的字符串标签?

数据挖掘 机器学习 scikit-学习 张量流 喀拉斯 编码
2021-09-22 22:34:09

我是机器学习和 keras 的新手,现在使用 keras 处理多类图像分类问题。输入是标记图像。经过一些预处理后,训练数据在 Python 列表中表示为:

[["dog", "path/to/dog/imageX.jpg"],["cat", "path/to/cat/imageX.jpg"], 
 ["bird", "path/to/cat/imageX.jpg"]]

“狗”、“猫”和“鸟”是类标签。我认为应该使用 one-hot 编码来解决这个问题,但我不太清楚如何处理这些字符串标签。LabelEncoder()以这种方式尝试过sklearn:

encoder = LabelEncoder()
trafomed_label = encoder.fit_transform(["dog", "cat", "bird"])
print(trafomed_label)

并且输出是 [2 1 0],这与我对 [[1,0,0],[0,1,0],[0,0,1]] 之类的期望输出不同。它可以通过一些编码来完成,但我想知道是否有一些“标准”或“传统”的方式来处理它?

3个回答

Sklearn 的LabelEncoder模块查找所有类并为每个类分配一个从 0 开始的数字 id。这意味着无论您的类表示在原始数据集中是什么,您现在都有一种简单一致的方式来表示每个类。它不进行 one-hot 编码,但正如您正确识别的那样,它非常接近,您可以使用这些 id 在其他代码中快速生成 one-hot 编码。

如果您想要 one-hot 编码,则可以LabelBinarizer改用。这非常相似:

 from sklearn.preprocessing import LabelBinarizer
 encoder = LabelBinarizer()
 transfomed_label = encoder.fit_transform(["dog", "cat", "bird"])
 print(transfomed_label)

输出:

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

使用 keras 中的图像生成器功能,我们可以直接提供示例代码:

datagen = tf.keras.preprocessing.image.ImageDataGenerator(
    featurewise_center=True,
    featurewise_std_normalization=True,
    rotation_range=20,
    width_shift_range=0.2,
    height_shift_range=0.2,
    horizontal_flip=True,
    validation_split=0.2)


img_size=128
train_generator = datagen.flow_from_directory('train',
                                                    target_size=(img_size, img_size),
                                                    subset='training',
                                                    batch_size=32)
X, y = next(train_generator)

print('Input features shape', X.shape)
print('Actual labels shape', y.shape)

使用它的另一个优点是,当我们对新文件进行预测时,我们可以使用train_generator.class_indices将标签从预测映射回实际的字符串名称。

您也可以sparse_categorical_crossentropy用作损失函数,然后您不需要onehot-encoding。
示例代码: model.compile(loss='sparse_categorical_crossentropy', optimizer='adam')

Keras 网站上的更多信息