Я пытаюсь использовать формат TFRecord для записи данных из C ++, а затем использовать его в python для кормления модели TensorFlow.
TL; DR; Простая сериализация протокольных сообщений в поток не удовлетворяет .tfrecord
требованиям формата Python TFRecordDataset
класса. Есть ли эквивалент Python TfRecordWriter
в C ++ (в TensorFlow или в библиотеках Google Protobuf) для генерации правильных .tfrecord
данных?
Подробности:
Упрощенный код C ++ выглядит так:
tensorflow::Example sample;
sample.mutable_features()->mutable_feature()->operator[]("a").mutable_float_list()->add_value(1.0);
std::ofstream out;
out.open("cpp_example.tfrecord", std::ios::out | std::ios::binary);
sample.SerializeToOstream(&out);
В Python для создания данных TensorFlow я пытаюсь использовать TFRecordDataset, но, по-видимому, он ожидает дополнительной информации верхнего / нижнего колонтитула в файле .tfrecord (а не простого списка сериализованных протокольных сообщений):
import tensorflow as tf
tfrecord_dataset = tf.data.TFRecordDataset(filenames="cpp_example.tfrecord")
next(tfrecord_dataset.as_numpy_iterator())
выход:
tensorflow.python.framework.errors_impl.DataLossError: corrupted record at 0 [Op:IteratorGetNext]
Обратите внимание, что с записанным двоичным файлом все в порядке, так как следующий код выводит корректный результат:
import tensorflow as tf
p = open("cpp_example.tfrecord", "rb")
example = tf.train.Example.FromString(p.read())
выход:
features {
feature {
key: "a"
value {
float_list {
value: 1.0
}
}
}
}
Анализируя двоичный вывод, сгенерированный моим примером C ++, и вывод, созданный с помощью Python TfRecordWriter
, я обнаружил дополнительные байты заголовка и нижнего колонтитула в содержимом. К сожалению, то, что представляют эти дополнительные байты, было деталью реализации (вероятно, тип сжатия и некоторая дополнительная информация), и я не мог отслеживать это глубже, чем какой-то класс в библиотеках python, который только что предоставил интерфейс из _pywrap_tfe.so
.
Был этот совет, в котором говорилось, что .tfrecord
— это просто обычные данные прототипа Google. . Возможно, мне не хватает знаний, где найти модуль записи данных protobuf (ожидайте сериализации протокольных сообщений в выходной поток)?
Оказывается,
tensorflow::io::RecordWriter
класс библиотеки TensorFlow C ++ выполняет свою работу.Было бы полезно, если бы на этот класс ссылались где-нибудь в документации TFRecord.
khkarens: У меня такая же проблема с различиями между сериализацией example.proto и TFRecord. Я создал тензорный поток для C ++ (с помощью tenorflow_cc floopcz), но теперь у меня возникают проблемы с компиляцией моей собственной программы из-за включенных в ваш ответ заголовков, требующих целого ряда файлов .cc). Моя программа построена вне тензорного потока, и мне нужно только сериализовать данные через protobufs, и мне бы очень хотелось избежать компиляции половины файлов .cc тензорного потока в моей небольшой программе. Как вам удалось скомпилировать приведенный выше код? — person khkarens; 21.05.2021