Загрузка записи Tensorflow из проблемы с массивами - PullRequest
0 голосов
/ 11 июня 2019

Я сохраняю предварительно обработанный звук в виде спектрограмм в TF.Record файлах. Пока все хорошо.

Мои данные (один образец) имеют форму (64, 23). Мой набор данных для тестирования имеет форму (N, 64, 23), где N - количество образцов.

Вот мой код для сохранения набора данных в TF.Record

def folder_to_tfrecord(self, X, Y, output_file):

    def _bytes_feature(value):
        return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))

    def _int64_feature(value):
        return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))

    writer = tf.python_io.TFRecordWriter(output_file)

    for i, (sample, label) in enumerate(zip(X, Y)):

        print(f'Storing example #{i} with shape {sample.shape} and label {label}')

        # Get Height and Width for future reconstruction
        height, width = sample.shape

        # Array to string
        sample_raw = sample.astype(np.float32).tostring()

        # Integer label
        label_raw = label

        example = tf.train.Example(features=tf.train.Features(feature={
            'height': _int64_feature(height),
            'width': _int64_feature(width),
            'data': _bytes_feature(sample_raw),
            'label': _int64_feature(label_raw)
        }))

        writer.write(example.SerializeToString())

    writer.close()

Какой вывод правильный:

Storing example #0 with shape (64, 23) and label 0
Storing example #1 with shape (64, 23) and label 0
Storing example #2 with shape (64, 23) and label 0
Storing example #3 with shape (64, 23) and label 0
Storing example #4 with shape (64, 23) and label 0

Но когда я пытаюсь использовать запись в TF.Dataset с активным исполнением (поэтому будут получены реальные данные), я получаю исключение (tensorflow keyerror)

Я читаю данные так:

import tensorflow as tf


def _parse_function(example_proto):

    keys_to_features = {
        'height': tf.FixedLenFeature([], tf.int64),
        'width': tf.FixedLenFeature([], tf.int64),
        'data': tf.FixedLenFeature([64, 23], tf.string),
        'label': tf.FixedLenFeature([], tf.int64)}

    parsed_features = tf.parse_single_example(example_proto, keys_to_features)

    return parsed_features['height'], \
        parsed_features['width'], \
        parsed_features['data'], \
        parsed_features['label']



def create_dataset(filepath = './new.tfrecord', paralel: int = 0):

    # This works with arrays as well
    dataset = tf.data.TFRecordDataset(filepath)

    # Maps the parser on every filepath in the array. You can set the number of parallel loaders here
    dataset = dataset.map(_parse_function)    

    return dataset


sess = tf.Session()
ds = create_dataset()
it = ds.make_one_shot_iterator()
next_data = it.get_next()

while True:
    try:
        data, label = sess.run(next_data)
        print(data)
        print(label)
    except tf.errors.OutOfRangeError:
        print("End of dataset")
        break

Я получил исключение tensorflow.python.framework.errors_impl.InvalidArgumentError: Key: data. Can't parse serialized Example.

Что я делаю не так? И есть ли возможность переформировать данные с учетом полей высоты и ширины?

EDIT: Когда я не использую нетерпеливое выполнение, конвейер данных работает

>>> print(next_data)
(<tf.Tensor 'IteratorGetNext:0' shape=() dtype=int64>, <tf.Tensor 'IteratorGetNext:1' shape=() dtype=int64>, <tf.Tensor 'IteratorGetNext:2' shape=(64, 23) dtype=string>, <tf.Tensor 'IteratorGetNext:3' shape=() dtype=int64>)

1 Ответ

0 голосов
/ 12 июня 2019

Я наконец заставил это работать.Мне пришлось отредактировать мою функцию синтаксического анализа и не передавать форму в FixedLenFeature.Я сохранил форму как часть объекта, а затем изменил ее форму с учетом этих значений.

def _parse_function(example_proto: 'Protocol Buffer') -> Tuple[tf.Tensor, tf.Tensor]:
    """Map function used as dataset.map(_parse_function) to back data back from the serialized
    from the protocol buffer

    Arguments:
        example_proto {[Protocol Buffer]} -- Incoming Proto

    Returns:
        Tuple[tf.Tensor, tf.Tensor] -- Returns tuple (image, label) where both of those are tf.Tensors
    """

    keys_to_features = {
        'height': tf.FixedLenFeature([], tf.int64),
        'width': tf.FixedLenFeature([], tf.int64),
        'data': tf.FixedLenFeature([], tf.string),
        'label': tf.FixedLenFeature([], tf.int64)}

    # Parse features
    parsed_features = tf.parse_single_example(example_proto, keys_to_features)

    # Decoder Scope
    with tf.variable_scope('decoder'):

        # Shape for reshaping image            
        height = parsed_features['height']
        width = parsed_features['width']

        # Label
        label = parsed_features['label']

        # Image
        image = tf.decode_raw(parsed_features['data'], tf.float32)           


    with tf.variable_scope('image'):
        image = tf.reshape(image, (height, width))

    return image, label
...