Преобразование TFRecords и tf.Examples в часто используемые типы данных - PullRequest
1 голос
/ 07 августа 2020

Я учусь создавать конвейеры TensorFlow Extended и считаю их очень полезными. Однако мне еще предстоит выяснить, как отлаживать и тестировать (табличные) данные, проходящие через эти конвейеры. Я знаю, что TensorFlow использует TFRecords / tf.Examples, которые являются protobufs.

Они могут читаться человеком с использованием TFRecordDataset и tf.Examples parseFromString. Тем не менее, этот формат трудно читать.

Как на самом деле проверить данные? Я чувствую, что мне нужен фрейм данных pandas. А поскольку у нас более 100 столбцов и разные варианты использования, я с трудом могу определять все столбцы каждый раз, когда хочу это делать. Могу я как-нибудь использовать для этого свою схему? Спасибо!

Edit : Я приму ответ @ TheEngineer, поскольку он дал мне ключевой намек на то, как достичь того, чего я хотел. Тем не менее, я хотел бы поделиться своим решением .

Отказ от ответственности: я использую этот код только для тестирования и просмотра того, что происходит в моем конвейере. Будьте осторожны при использовании этого кода в производстве. Могут быть способы лучше и безопаснее.

import sys 
import numpy as np
import tensorflow_data_validation as tfdv 

# Our default values for missing values within the tfrecord. We'll restore them later
STR_NA_VALUE = "NA"
INT_NA_VALUE = -sys.maxsize - 1
FLOAT_NA_VALUE = float("nan")

# Create a dict containing FixedLenFeatures using our schema
def load_schema_as_feature_dict(schema_path):
    schema = tfdv.load_schema_text(schema_path)

    def convert_feature(feature):
        if feature.type == 1:
            return tf.io.FixedLenFeature((), tf.string, STR_NA_VALUE)
        if feature.type == 2:
            return tf.io.FixedLenFeature((), tf.int64, INT_NA_VALUE)
        if feature.type == 3:
            return tf.io.FixedLenFeature((), tf.float32, FLOAT_NA_VALUE)
        raise ValueError("Non-implemented type {}".format(feature.type))

    return dict((feature.name, convert_feature(feature)) for feature in schema.feature)  

def as_pandas_frame(tfrecord_path, schema_path):
    feature_dict = load_schema_as_feature_dict(schema_path)
    dataset = tf.data.TFRecordDataset(tfrecord_path, compression_type="GZIP")
    parsed_dataset = dataset.map(lambda serialized_example: tf.io.parse_single_example(serialized_example, feature_dict))
    df = pd.DataFrame(list(parsed_dataset.as_numpy_iterator()))
    
    # Restore NA values from default_values we had to set
    for key, value in {np.object: str.encode(STR_NA_VALUE), np.int64: INT_NA_VALUE, np.float: FLOAT_NA_VALUE}.items():
        type_columns = df.select_dtypes(include=[key]).columns
        df[type_columns] = df[type_columns].replace({value:None})
    
    return df

Теперь вам просто нужно вызвать эту функцию с сохраненными tfrecords и файлом schema.pbtxt:

df = as_pandas_frame("path/to/your/tfrecord.gz", "path/to/your/schema.pbtxt")

1 Ответ

1 голос
/ 07 августа 2020

Я не уверен, что вы имеете в виду под TFRecordDataset, что трудно прочитать. Но это пример того, как я бы использовал свои данные TFRecord. Feature_description содержит функции, которые хранятся в каждом сэмпле в TFRecord (и их тип данных). После загрузки записей таким образом вы можете делать с ними все виды вещей, включая пакетирование, увеличение, перемешивание в конвейере или доступ к отдельным файлам, преобразование их на numpy и c.

import tensorflow as tf
import numpy as np
from PIL import Image

filenames = []
for i in range(128):
    name = "./../result/validation-%.5d-of-%.5d" % (i, 128)
    filenames.append(name)

def read_tfrecord(serialized_example):
    feature_description = {
            'image/height': tf.io.FixedLenFeature((), tf.int64),
            'image/width': tf.io.FixedLenFeature((), tf.int64),
            'image/colorspace': tf.io.FixedLenFeature((), tf.string),
            'image/channels': tf.io.FixedLenFeature((), tf.int64),
            'image/class/label': tf.io.FixedLenFeature((), tf.int64),
            'image/encoded': tf.io.FixedLenFeature((), tf.string),
    }

    parsed_features = tf.io.parse_single_example(serialized_example, feature_description)

    parsed_features['image/encoded'] = tf.io.decode_jpeg(
            parsed_features['image/encoded'], channels=3)

    return parsed_features



data = tf.data.TFRecordDataset(filenames)


parsed_dataset = data.shuffle(128).map(read_tfrecord).batch(128)


for sample in parsed_dataset.take(1):
        numpyed = sample['image/encoded'].numpy()
        img = Image.fromarray(numpyed, 'RGB')
        img.show()
        tf.print(sample['image/class/label'])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...