【问题标题】:How to generate/read sparse sequence labels for CTC loss within Tensorflow?如何在 Tensorflow 中为 CTC 损失生成/读取稀疏序列标签?
【发布时间】:2017-07-23 13:02:01
【问题描述】:

从带有转录的单词图像列表中,我尝试使用tf.train.slice_input_producer 创建和读取稀疏序列标签(对于tf.nn.ctc_loss),避免

  1. 将预打包的训练数据序列化到磁盘中 TFRecord 格式

  2. tf.py_func 的明显局限性,

  3. 任何不必要或过早的填充,以及

  4. 将整个数据集读取到 RAM。

主要问题似乎是将字符串转换为tf.nn.ctc_loss 所需的标签序列(SparseTensor)。

例如,对于(有序)范围[A-Z] 中的字符集,我想将文本标签字符串"BAD" 转换为序列标签类列表[1,0,3]

我要读取的每个示例图像都包含作为文件名一部分的文本,因此可以直接在 python 中提取和进行转换。 (如果有办法在 TensorFlow 计算中做到这一点,我还没有找到。)

之前的几个问题扫了一眼这些问题,但一直没能成功整合。例如,

有没有办法整合这些方法?

另一个示例(SO question #38012743)显示了我如何延迟从字符串到列表的转换,直到将文件名出列进行解码,但它依赖于 tf.py_func,它有一些警告。 (我应该担心他们吗?)

我认识到“SparseTensors 不能很好地处理队列”(根据 tf 文档),因此可能需要在批处理之前对结果(序列化?)做一些巫术,甚至在计算发生的地方返工;我对此持开放态度。

按照 MarvMind 的大纲,这是一个包含我想要的计算的基本框架(遍历包含示例文件名的行,提取每个标签字符串并转换为序列),但我还没有成功确定“Tensorflow”的方法来做到这一点。

感谢您的正确“调整”、更适合我的目标的策略,或者表明 tf.py_func 不会破坏训练效率或其他下游(例如,加载经过训练的模型以供将来使用)。

编辑(+7 小时) 我发现了缺失的操作来修补问题。虽然仍需要验证这与下游 CTC_Loss 的连接,但我已经检查了下面的编辑版本是否正确地批处理和读取图像和稀疏张量。

out_charset="ABCDEFGHIJKLMNOPQRSTUVWXYZ"

def input_pipeline(data_filename):
    filenames,seq_labels = _get_image_filenames_labels(data_filename)
    data_queue = tf.train.slice_input_producer([filenames, seq_labels])
    image,label = _read_data_format(data_queue)
    image,label = tf.train.batch([image,label],batch_size=2,dynamic_pad=True)
    label = tf.deserialize_many_sparse(label,tf.int32)
    return image,label

def _get_image_filenames_labels(data_filename):
    filenames = []
    labels = []
    with open(data_filename)) as f:
        for line in f:
            # Carve out the ground truth string and file path from 
            # lines formatted like:
            # ./241/7/158_NETWORK_51375.jpg 51375
            filename = line.split(' ',1)[0][2:] # split off "./" and number
            # Extract label string embedded within image filename
            # between underscores, e.g. NETWORK
            text = os.path.basename(filename).split('_',2)[1]
            # Transform string text to sequence of indices using charset, e.g.,
            # NETWORK -> [13, 4, 19, 22, 14, 17, 10]
            indices = [[i] for i in range(0,len(text))]
            values = [out_charset.index(c) for c in list(text)]
            shape = [len(text)]
            label = tf.SparseTensorValue(indices,values,shape)
            label = tf.convert_to_tensor_or_sparse_tensor(label)
            label = tf.serialize_sparse(label) # needed for batching
            # Add data to lists for conversion
            filenames.append(filename)
            labels.append(label)
    filenames = tf.convert_to_tensor(filenames)
    labels = tf.convert_to_tensor_or_sparse_tensor(labels)
    return filenames, labels

def _read_data_format(data_queue):
    label = data_queue[1]
    raw_image = tf.read_file(data_queue[0])
    image = tf.image.decode_jpeg(raw_image,channels=1)
    return image,label

【问题讨论】:

    标签: python tensorflow recurrent-neural-network


    【解决方案1】:

    关键思想似乎是从所需数据创建SparseTensorValue,将其传递给tf.convert_to_tensor_or_sparse_tensor,然后(如果您想批量处理数据)使用tf.serialize_sparse 对其进行序列化。批处理后,您可以使用tf.deserialize_many_sparse 恢复值。

    这是大纲。创建稀疏值,转换为张量,并序列化:

    indices = [[i] for i in range(0,len(text))]
    values = [out_charset.index(c) for c in list(text)]
    shape = [len(text)]
    label = tf.SparseTensorValue(indices,values,shape)
    label = tf.convert_to_tensor_or_sparse_tensor(label)
    label = tf.serialize_sparse(label) # needed for batching
    

    然后,您可以进行批处理和反序列化:

    image,label = tf.train.batch([image,label],dynamic_pad=True)
    label = tf.deserialize_many_sparse(label,tf.int32)
    

    【讨论】:

      猜你喜欢
      • 2017-04-08
      • 1970-01-01
      • 2018-01-16
      • 2020-08-31
      • 2020-10-12
      • 1970-01-01
      • 2020-12-04
      • 2020-04-28
      • 1970-01-01
      相关资源
      最近更新 更多