Группировать набор данных tensorflow по ключу и пакет по ключу

#python #tensorflow #machine-learning #tensorflow-datasets

#python #tensorflow #машинное обучение #tensorflow-datasets

Вопрос:

В настоящее время я работаю над проблемой в tensorflow, где мне нужно создавать пакеты, в которых все тензоры в пакете имеют определенное ключевое значение. Если возможно, я пытаюсь использовать dataset api. Возможно ли это?

Фильтровать, сопоставлять, применять — все это работает с отдельными элементами, где мне нужен метод группировки по ключу. Я наткнулся на tf.data.experimental.group_by_window и tf.data.experimental.group_by_reducer, которые кажутся многообещающими, но я не смог выработать решение.

Возможно, было бы лучше привести пример:

 dataset:

feature,label
1,word1
2,word2
3,word3
1,word1
3,word3
1,word1
1,word1
2,word2
3,word3
1,word1
3,word3
1,word1
1,word1
  

группировать по «ключевой» функции, максимальный размер пакета = 3, предоставляя пакеты:

 batch1
[[1,word1],
 [1,word1],
 [1,word1]]
batch2
[[1,word1],
 [1,word1],
 [1,word1]]
batch3
[[1,word1]]
batch4
[[2,word2]
 [2,word2]]
batch5
[[3,word3],
 [3,word3],
 [3,word3]]
batch6
[[3,word3]]
  

РЕДАКТИРОВАТЬ: порядок каждого пакета не важен, несмотря на пример

Ответ №1:

Я думаю, что это выполняет преобразование, которое вы хотите:

 import tensorflow as tf
import random

random.seed(100)
# Input data
label = list(range(15))
# Shuffle data
random.shuffle(label)
# Make feature from label data
feature = [lbl // 5 for lbl in label]
batch_size = 3

print('Data:')
print(*zip(feature, label), sep='n')

with tf.Graph().as_default(), tf.Session() as sess:
    # Make dataset from data arrays
    ds = tf.data.Dataset.from_tensor_slices({'feature': feature, 'label': label})
    # Group by window
    ds = ds.apply(tf.data.experimental.group_by_window(
        # Use feature as key
        key_func=lambda elem: tf.to_int64(elem['feature']),
        # Convert each window to a batch
        reduce_func=lambda _, window: window.batch(batch_size),
        # Use batch size as window size
        window_size=batch_size))
    # Iterator
    iter = ds.make_one_shot_iterator().get_next()
    # Show dataset contents
    print('Result:')
    while True:
        try:
            print(sess.run(iter))
        except tf.errors.OutOfRangeError: break
  

Вывод:

 Data:
(2, 11)
(1, 8)
(2, 12)
(0, 3)
(1, 9)
(0, 0)
(0, 4)
(0, 1)
(2, 10)
(1, 5)
(1, 6)
(2, 14)
(2, 13)
(1, 7)
(0, 2)
Result:
{'feature': array([0, 0, 0]), 'label': array([3, 0, 4])}
{'feature': array([2, 2, 2]), 'label': array([11, 12, 10])}
{'feature': array([1, 1, 1]), 'label': array([8, 9, 5])}
{'feature': array([0, 0]), 'label': array([1, 2])}
{'feature': array([1, 1]), 'label': array([6, 7])}
{'feature': array([2, 2]), 'label': array([14, 13])}
  

Комментарии:

1. В TF2 вы бы немного изменили код: # Make dataset from data arrays ds = tf.data.Dataset.from_tensor_slices({'feature': feature, 'label': label}) # Group by window ds = ds.apply(tf.data.experimental.group_by_window( # Use feature as key key_func=lambda elem: tf.cast(elem['feature'], tf.int64), # Convert each window to a batch reduce_func=lambda _, window: window.batch(batch_size), # Use batch size as window size window_size=batch_size)) # Show dataset contents print('Result:') for element in ds: print(element)