【问题标题】:How to write LabelEncoder in Tensorflow?如何在 Tensorflow 中编写 LabelEncoder?
【发布时间】:2020-07-06 16:24:23
【问题描述】:

我正在尝试将 Google Storage 上的目录解析为字符串,但我不断收到错误消息。我想找到每个文件的目录并将目录名称的数字编码作为数据集返回。这在使用 LabelEncoder 的 sklearn 中是微不足道的,但我在 Tensorflow 中遇到了麻烦。

CLASS_NAMES = [b'class_1', b'class_2', b'class_3']
labeler = tfds.features.ClassLabel(names=CLASS_NAMES)

def parse_filenames(filename):
    label = tf.strings.split(tf.expand_dims(filename, axis=-1), sep='/')
    label = label.values[-2]

    # Problem is in the two lines below
    position_feature = tf.feature_column.categorical_column_with_vocabulary_list('label_names', CLASS_NAMES)
    label = tf.io.parse_example(label, features=position_feature)

    return label

folder = b'gs://<bucket>/train/*/*.jpg'
filenames_dataset = tf.data.Dataset.list_files(folder)
label_dataset = filenames_dataset.map(parse_filenames)

next(iter(label_dataset))

我收到一个错误ValueError: dictionary update sequence element #0 has length 16; 2 is required

如果我取出“# Problem is here”注释下的两行,它工作正常,除了它返回一个字符串而不是整数。我尝试过其他非张量流选项,例如 .index(label),但这些选项当然会失败,因为一切都是张量而不是字符串。还有其他方法吗?

【问题讨论】:

    标签: python tensorflow keras


    【解决方案1】:

    也许你可以试试这一行而不是这两行:

    label = tf.argmax(tf.cast(parts[-2] == CLASS_NAMES, tf.int32))
    

    你会得到类似[0, 1, 0]的东西(CLASS_NAMES中标签的索引)。

    功能和可重现的示例:

    import tensorflow as tf
    import numpy as np
    from string import ascii_lowercase as letters
    
    CLASS_NAMES = [b'class_1', b'class_2', b'class_3']
    
    files = ['\\'.join([np.random.choice(CLASS_NAMES).decode(),
                        ''.join(np.random.choice(list(letters), 5)) + '.jpg']) 
             for i in range(10)]
    
    ds = tf.data.Dataset.from_tensor_slices(files)
    

    这是我生成的假文件:

    ['class_3\\jrxog.jpg',
     'class_1\\slfiq.jpg',
     'class_2\\svldd.jpg',
     'class_2\\avrgt.jpg',
     'class_3\\wqwuv.jpg']
    

    现在实现这个:

    def get_label(file_path):
        parts = tf.strings.split(file_path, '\\')
        return file_path, tf.argmax(tf.cast(parts[-2] == CLASS_NAMES, tf.int32))
    
    ds = ds.map(get_label)
    
    next(iter(ds))
    
    (<tf.Tensor: shape=(), dtype=string, numpy=b'class_1\\bbqrx.jpg'>,
     <tf.Tensor: shape=(), dtype=int64, numpy=0>)
    

    【讨论】:

    • 感谢您的帮助。这会产生单热编码。我正在尝试编码为单个 int,因此 class_1 -> 0、class_2 -> 1 等。
    • 感谢您的反馈。我改了。
    • 你可以把return语句中的file_path去掉,只是为了演示
    • 完美。感谢您的帮助。
    【解决方案2】:

    我使用了 sklearn 的标签编码器。这是您可能必须腌制的东西,这样您以后就可以反向转换您的结果。我还是新手,所以我不确定这对你有多好

    【讨论】:

      猜你喜欢
      • 2021-01-26
      • 2016-12-09
      • 2021-01-21
      • 2016-12-27
      • 1970-01-01
      • 1970-01-01
      • 2016-04-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多