繁体   English   中英

如何将字符串映射到 int(类号)作为 tf.data.Dataset .map() 的一部分在 Tensorflow 中进行预处理?

[英]How to map string to a int (class number) as a part of tf.data.Dataset .map() for preprocessing in Tensorflow?

我正在尝试创建一个解析器函数,该函数从 TFRecord 读取(图像、标签)对。 当标签是 int64 时,一切正常,但是当我尝试将标签保存为字符串并在解析器函数中将其转换为 int 时,事情就中断了。 我对这个框架还是个新手,所以我下面的实现使用了急切的 .numpy(),当我将 .map 应用到 tf.data.Dataset 时它不起作用。

一些背景:我的数据集中有层次结构,就像在这个例子中我使用“狗”和“拉布拉多”来表示这一点一样。 我想允许训练可以对分类图像(猫、狗)进行分类的数据,还可以训练可以从相同标记数据中对更具体类型(斗牛犬、拉布拉多犬)进行分类的模型,这些数据通常具有最具体类型的标签在图像上。

这就是我试图做的:

#!/usr/bin/env python3
import tensorflow as tf
import functools

# example: this model classifies dogs and cats. this map translates a specific dog type to the "dog" label, 
# and the same for cats. all other labels would go to the negative class "neg".
example_label_map = {
    "bulldog": "dog",
    "labrador": "dog",
    "persian cat": "cat",
    "cow": "neg",
}

# map the N classes to an int of 0..N-1
labels_to_class_int = {
    "neg": 0,   # negative class
    "dog": 1,
    "cat": 2,
}

def parse_tfrec_function(example, labels_map):
    """
    labels is a map of labels to class numbers. e.g. "bulldog" -> 1, "labrador" -> 1, "persian cat" -> 2, ...
    """
    image_feature_description = {
        "image": tf.io.FixedLenFeature([], tf.string),
        "label": tf.io.FixedLenFeature([], tf.string)
    }

    features = tf.io.parse_single_example(example, image_feature_description)

    image = tf.io.parse_tensor(features["image"], tf.uint8)
    
    # *** the following fails. how can this be done efficiently (lazy)?
    label = features["label"].numpy().decode('utf-8')
    class_num = labels_map[label]

    return image, class_num


tfrec_file = ['/path/to/dataset.tfrec']
dataset = tf.data.TFRecordDataset(tfrec_file)

labels_map = {}
for k, v in example_label_map.items():
    labels_map[k] = labels_to_class_int[v]

print(labels_map)

parser_fn = functools.partial(parse_tfrec_function, labels_map=labels_map)
parset_dataset = dataset.map(parser_fn)

失败原因,因为它试图急切地运行:

AttributeError: 'Tensor' object has no attribute 'numpy'

正确的做法是什么? 如果我想训练一个更具体的网络以区分特定的类子集,则将类编号存储在 TFRecord 中需要使用几乎相同的数据制作不同的 TFRecord。

给定作为预处理步骤运行的映射(tf.data.Dataset 的 .map),如何将标签字符串有效地转换为类号?

谢谢!

IIUC 问题实际上是关于在图形模式下将字符串重新映射到 int。 我认为应该可以使用tf.case执行此string- >int 重新映射。

一个例子:

import tensorflow.compat.v1 as tf                                               
tf.disable_eager_execution()                                                    
                                                                             
                                                                                
def remap_string_to_int(tensor: tf.Tensor) -> tf.Tensor:                        
    pred_fn_pairs = [                                                           
        (tf.equal(tensor, 'neg'), lambda: 0),                                   
        (tf.equal(tensor, 'dog'), lambda: 1),                                   
        (tf.equal(tensor, 'cat'), lambda: 2),                                   
    ]                                                                           
    return tf.case(pred_fn_pairs)                           
                                                                                                                       
with tf.Session() as sess:                                                      
    label_tensor = tf.placeholder(tf.string, [])                                
    label_int_tensor = remap_string_to_int(label_tensor)                        
    print("int-value is: ",                                                     
          sess.run(label_int_tensor, feed_dict={label_tensor: 'dog'}))

印刷:

>>> int-value is:  1

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM