Как я могу преобразовать список индексов в 1d логический тензор

#python #tensorflow

Вопрос:

Я хотел бы, чтобы функция tf.возвращала 1d логический тензор фиксированной длины с каждым соответствующим диапазоном индексов в значение True из файла меток. Диапазоны индексов могут перекрываться. Но я застрял при преобразовании индексов в плоский булев тензор.

Я читаю файл, в котором каждая строка является меткой и начальным и конечным индексом фиксированной длины. Для этого примера мы можем сказать, что фиксированная длина равна 50.

Пример содержимого файла меток:

 frog 4.0 10.0
frog 20.0 30.0
goat 2.0 20.0
camel 4.0 15.0
 

Вот это было бы

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

Это функция tf., которая до сих пор хорошо работает, но я застрял на том, как получить окончательный тензор. Я выполняю эту функцию tf., используя dataset.map(load_label).

 def load_label(file_path, accepted_labels=['goat', 'frog']):
    label_datas = tf.io.read_file(file_path)
    label_datas = tf.strings.strip(label_datas)
    label_datas = tf.strings.split(label_datas, sep='n')
    label_datas = tf.strings.split(label_datas, sep=' ')

    label_datas = label_datas.to_tensor(default_value='0.0', shape=[None, 3])

    list_of_indices = []
    for label_data in label_datas:
        equal = tf.math.equal(label_data[0], accepted_labels)
        if tf.reduce_any(equal):
            start = tf.strings.to_number(label_data[1], out_type=tf.float32)
            end = tf.strings.to_number(label_data[2], out_type=tf.float32)
            start = tf.cast(start, tf.int32)
            end = tf.cast(end, tf.int32)

            list_of_indices.append(tf.range(start, end, 1))

    list_of_indices = tf.concat(list_of_indices, axis=0)

    list_of_indices, idx = tf.unique(list_of_indices)
 

Ответ №1:

Я действительно нашел решение, используя TensorArray и reduce_sum.

Я уверен, что его можно еще больше оптимизировать. Вот он:

 def load_label(file_path, accepted_labels=['goat', 'frog']):
    label_datas = tf.io.read_file(file_path)
    label_datas = tf.strings.strip(label_datas)
    label_datas = tf.strings.split(label_datas, sep='n')
    label_datas = tf.strings.split(label_datas, sep=' ')

    label_datas = label_datas.to_tensor(default_value='0.0', shape=[None, 3])

    label_ta = tf.TensorArray(tf.int32, size=0, dynamic_size=True, clear_after_read=False)
    ta_index_count = 0
    for label_data in label_datas:
        equal = tf.math.equal(label_data[0], accepted_labels)
        if tf.reduce_any(equal):
            start = tf.strings.to_number(label_data[1], out_type=tf.float32)
            end = tf.strings.to_number(label_data[2], out_type=tf.float32)
            start = tf.cast(start, tf.int32)
            end = tf.cast(end, tf.int32)

            label_ta = label_ta.write(ta_index_count, tf.concat(
                [tf.zeros((start), dtype=tf.int32),
                 tf.ones((end - start), dtype=tf.int32),
                 tf.zeros((new_length - end), dtype=tf.int32)], 0))
        else:
            label_ta = label_ta.write(ta_index_count, tf.zeros((new_length), dtype=tf.int32))
        ta_index_count = ta_index_count   1

    label_ta = label_ta.stack()
    label_ta = tf.reduce_sum(label__ta, 0)
    label_ta = tf.where(label_ta > 0, 1, 0)
    return label_ta