"Введение"TFRecord является важным компонентом экосистемы TensorFlow. Это формат хранения двоичных последовательностей. Использование этого формата может сделать чтение и обработку входных данных более эффективными, тем самым повышая скорость общего процесса обучения. Чрезвычайно гибкий, он может облегчить построение и анализ данных сложных признаков. В этой статье подробно описан процесс создания и чтения файлов данных TFRecord, а также предоставлен соответствующий пример кода для справки.
Введение в формат TFRecord
TFRecord
даTensorFlow
Важный компонент экосистемы, который по сути является файловым форматом для хранения содержимого двоичных последовательностей.TFRecord
Файл сериализуетсяprotobuf
структура данных, которая может быть предоставлена напрямуюTensorFlow
Программа для чтения и использования для обучения модели.
Для файлов данных в текстовом формате накладные расходы на хранение и чтение относительно велики.TFRecord
Отформатированные файлы данных занимают меньше места на диске и читаются более эффективно, поэтому используйтеTFRecord
Формат хранения может в определенной степени повысить эффективность обработки данных.
Кроме того, данные в текстовом формате больше подходят для обработки定长且维度单一的
характерные данные, для变长以及多维度的
Обработка данных признаков будет более проблематичной, иTFRecord
Отформатированные данные не имеют этого ограничения, что обеспечивает большую гибкость при чтении и обработке данных.
TFRecord ProtoBuf
при создании или чтенииTFRecord
файл, нам нужно соединиться сTFRecord
зависит от форматаprotobuf
протоколы имеют определенное понимание того, что они составленыTFRecord
важная часть документа.
Example
Example
Относится к выборке входных данных, которая состоит из ряда функций. Тотprotobuf
Формат следующий:
message Example {
Features features = 1;
}
вышеFeatures
относится к совокупности признаков, которыеprotobuf
Формат следующий:
message Features {
// Map from feature name to feature.
map<string, Feature> feature = 1;
}
здесьFeatures
использоватьmap
конструкция для хранения, гдеmap
изkey
представляет имя функции, котораяstring
тип,value
представляет конкретное собственное значение, котороеFeature
тип.
Кроме того, можно увидетьExample
только что инкапсулированныйFeatures
структура, суть которойFeatures
эквивалентны.
Feature
Feature
относится к определенному собственному значению, котороеprotobuf
Формат следующий:
message Feature {
// Each feature can be exactly one kind.
oneof kind {
BytesList bytes_list = 1;
FloatList float_list = 2;
Int64List int64_list = 3;
}
}
отFeature
Как видно из определения, он может принимать данные в трех форматах, а именно:
-
BytesList
формат, который может представлятьstring
илиbyte
тип данных. -
FloatList
формат, который может представлятьfloat
иdouble
тип данных. -
Int64List
формат, который может представлятьbool
тип,enum
тип,int32
тип,uint32
тип,int64
тип иuint64
и многие другие типы данных.
Вышеупомянутые три формата в основном охватывают все распространенные типы ввода данных и используются для генерации и анализа.TFRecord
данные, вы можете использовать соответствующие данные в соответствии с конкретным типом данныхFeature
структура.
Реализация Python
вышеprotobuf
После преобразования файлов в структуры данных для конкретного языка эти структуры можно использовать для построения и сериализации данных объектов. Ниже сpython
Язык в качестве примера, чтобы представить конкретное использование этих структур данных. (Примечание: вTensorFlow
изpython
Инсталляционный пакет уже содержитExample
а такжеFeature
и другие связанные структуры данных, мы можем использовать их напрямую без повторного использованияprotoc
Инструмент создан. )
Во-первых, нам нужно построитьFeature
объект. так какFeature
Структурная поддержка3
данные в различных форматах, поэтому здесь мы используем3
функция для создания различных типовFeature
объект. Пример кода выглядит следующим образом:
import tensorflow as tf
import numpy as np
def _bytes_feature(value):
"""Returns a bytes_list from a string / byte."""
if isinstance(value, type(tf.constant(0))):
# BytesList won't unpack a string from an EagerTensor.
value = value.numpy()
return tf.train.Feature(bytes_list=tf.train.BytesList(value=[value]))
def _float_feature(value):
"""Returns a float_list from a float / double."""
return tf.train.Feature(float_list=tf.train.FloatList(value=[value]))
def _int64_feature(value):
"""Returns an int64_list from a bool / enum / int / uint."""
return tf.train.Feature(int64_list=tf.train.Int64List(value=[value]))
# Print BytesList.
print(_bytes_feature(b'test_string'))
print(_bytes_feature(u'test_bytes'.encode('utf-8')))
# Print FloatList.
print(_float_feature(np.exp(1)))
# Print Int64List.
print(_int64_feature(True))
print(_int64_feature(1))
# Serialize and Deserialize Feature.
serialized_feature = _float_feature(np.exp(1)).SerializeToString()
print(serialized_feature)
feature_proto = tf.train.Feature.FromString(serialized_feature)
print(feature_proto)
в_bytes_feature
,_float_feature
и_int64_feature
функции используются для созданияBytesList
,FloatList
иInt64List
форматированныйFeature
объект, предполагается, что это3
параметры функцииvalue
являются единым значением.
так какtf.train.*List
Аргументы, полученные функцией, представляют собой списки (list
) или массив (array
), поэтому приведенный выше код добавит[]
нотация для представления списка, если входной параметрvalue
Эта операция не требуется, если это уже список или массив. Кроме того, необходимо обратить внимание на3
параметры функцииvalue
Основной тип*List
совпадают, иначе будет сообщено об ошибке.
в сгенерированномFeature
объект, вы можете назвать егоSerializeToString
метод сериализации, в результате чего получается сериализованная строка. Также вы можете использоватьtf.train.Feature.FromString
метод восстановления сериализованных данных вFeature
объект.
Затем мы можем построитьExample
объект и сериализовать его. Предположим, у нас есть4
своего родаFeature
, они естьboolean
типовые характеристики,integer
типовые характеристики,string
типовые характеристики иfloat
характеристики типа, мы сначала4
вид функции через выше3
После кодирования функция возвращает соответствующийFeature
объект, затем построитьFeature Map
словарь и сгенерироватьFeatures
объект, последний использованныйFeatures
генерация объектаExample
объект и сериализовать его. Объедините вышеуказанный процесс в одну функциюserialize_example
, его пример кода выглядит следующим образом:
def serialize_example(feature0, feature1, feature2, feature3):
"""
Creates a tf.train.Example message ready to be written to a file.
"""
# Create a dictionary mapping the feature name to the tf.train.Example-compatible
feature = {
'feature0': _int64_feature(feature0),
'feature1': _int64_feature(feature1),
'feature2': _bytes_feature(feature2),
'feature3': _float_feature(feature3),
}
# Create a Features message using tf.train.Example.
example_proto = tf.train.Example(features=tf.train.Features(
feature=feature))
return example_proto.SerializeToString()
# Serialize and Deserialize Example.
serialized_example = serialize_example(False, 4, b'goat', 0.9876)
print(serialized_example)
example_proto = tf.train.Example.FromString(serialized_example)
print(example_proto)
Точно так же вы можете позвонитьExample
объектSerializeToString
чтобы сериализовать его в строку, вызовитеtf.train.Example.FromString
способ сериализацииExample
Реставрация объекта.
Генерация файла TFRecord
Предположим, у нас есть4
видыFeature
, как описано в предыдущем разделе, и предполагая их исходные данные (numpy
) создается, как показано в следующем коде:
# The number of observations in the dataset.
n_observations = int(1e4)
# Boolean feature, encoded as False or True.
feature0 = np.random.choice([False, True], n_observations)
# Integer feature, random from 0 to 4.
feature1 = np.random.randint(0, 5, n_observations)
# String feature.
strings = np.array([b'cat', b'dog', b'chicken', b'horse', b'goat'])
feature2 = strings[feature1]
# Float feature, from a standard normal distribution.
feature3 = np.random.randn(n_observations)
print(feature0, feature1, feature2, feature3)
Теперь мы собираемся использовать это4
своего родаFeature
для создания содержащего10,000
образцов данныхTFRecord
файл можно создать следующими способами.
Сгенерировано с использованием tf.data
первое использованиеtf.data.Dataset.from_tensor_slices
функция для созданияdateset
, код выглядит так:
features_dataset = tf.data.Dataset.from_tensor_slices(
(feature0, feature1, feature2, feature3))
# Print dataset.
print(features_dataset)
# Print one element in dataset.
for f0, f1, f2, f3 in features_dataset.take(1):
print(f0, f1, f2, f3)
Затем мы используем определение, определенное в предыдущем разделе.serialize_example
функция для создания сериализованного строкового типаdataset
, код выглядит так:
def generator():
for features in features_dataset:
yield serialize_example(*features)
serialized_features_dataset = tf.data.Dataset.from_generator(
generator,
output_types=tf.string,
output_shapes=(),
)
# Print serialized dataset.
print(serialized_features_dataset)
# Print one element in serialized_features_dataset.
for s in serialized_features_dataset.take(1):
print(s)
Наконец, мы сериализуемdataset
написатьTFRecord
В файле код выглядит так:
filename = 'train.tfrecord'
writer = tf.data.experimental.TFRecordWriter(filename)
writer.write(serialized_features_dataset)
Обратите внимание здесьwriter
используетtf.data.experimental.TFRecordWriter
объект, посвященныйсерийныйdataset
объект записывается вTFRecord
В файле, который будет описан позжеtf.io.TFRecordWriter
объекты различаются.
Сгенерировано с помощью tf.io
Сначала преобразуйте каждую выборку данных вtf.train.Example
объект и сериализовать его перед записьюTFRecord
В файле используется то же, что описано выше здесьserialize_example
функция для сериализации, код выглядит следующим образом:
# Write the `tf.train.Example` observations to the file.
with tf.io.TFRecordWriter(filename) as writer:
for i in range(n_observations):
example = serialize_example(
feature0[i],
feature1[i],
feature2[i],
feature3[i],
)
writer.write(example)
здесьwriter
используетtf.io.TFRecordWriter
объект, который напрямую записывает сериализованную строку вTFRecord
в файле.
В общем, это поколениеTFRecord
файл вpython
Он наиболее часто используется и может быть выбран в соответствии с конкретной ситуацией при фактическом использовании.
Сгенерировано с помощью MapReduce
Во время обработки данных мы можем использоватьMapReduce
Проведем некоторые операции предварительной обработки, а также надеемся, что сможем напрямую использоватьMapReduce
задача создать несколькоTFRecord
файлы данных для использования в распределенном обучении, чтобы удовлетворить эту потребность,TensorFlow
Eco предоставляет библиотеку расширенийtensorflow-hadoop
, который содержитTFRecord
форматированныйMapReduce InputFormat
иOutputFormat
выполнить. Используя эту библиотеку расширений, мы можем напрямую использоватьMapReduce
задачи для создания и чтенияTFRecord
файл. Часть кода примера выглядит следующим образом:
// Main function.
import org.tensorflow.hadoop.io.TFRecordFileOutputFormat;
Job job = Job.getInstance(config, "TFRecord");
job.setOutputFormatClass(TFRecordFileOutputFormat.class);
// Mapper or Reducer.
import java.util.Arrays;
import com.google.protobuf.ByteString;
import org.tensorflow.example.BytesList;
import org.tensorflow.example.Example;
import org.tensorflow.example.Feature;
import org.tensorflow.example.Features;
import org.tensorflow.example.FloatList;
import org.tensorflow.example.Int64List;
// map or reduce function
// *List value.
Int64List value0 = Int64List.newBuilder().addAllValue(Arrays.asList(0L)).build();
Int64List value1 = Int64List.newBuilder().addAllValue(Arrays.asList(4L)).build();
BytesList value2 = BytesList.newBuilder()
.addAllValue(Arrays.asList(ByteString.copyFrom("goat".getBytes()))).build();
FloatList value3 = FloatList.newBuilder().addAllValue(Arrays.asList(0.9876f)).build();
// All features.
Feature feature0 = Feature.newBuilder().setInt64List(value0).build();
Feature feature1 = Feature.newBuilder().setInt64List(value1).build();
Feature feature2 = Feature.newBuilder().setBytesList(value2).build();
Feature feature3 = Feature.newBuilder().setFloatList(value3).build();
// Feature map.
Features feature = Features.newBuilder().putFeature("feature0", feature0)
.putFeature("feature1", feature1).putFeature("feature2", feature2)
.putFeature("feature3", feature3).build();
// Example.
Example example = Example.newBuilder().setFeatures(feature).build();
// Write to TFRecord file.
context.write(new BytesWritable(example.toByteArray()), NullWritable.get());
Обратите внимание, что для соответствияhadoop
версия, вам может потребоваться изменитьtensorflow-hadoop
в исходном кодеpom.xml
файл, будетhadoop.version
установите то, что вы используетеhadoop
версию и использоватьmaven
инструмент для перекомпиляции проекта, затем сгенерированныйjar
пакет, импортированный вMapReduce
В проекте избегайте ошибок из-за несоответствия версий.
Кроме того, чтобы сделатьMapReduce
Проект можно нормально скомпилировать, нужно еще импортироватьorg.tensorflow:proto
библиотека, а такжеcom.google.protobuf:protobuf-java
библиотека, доступная изmaven
Официальный репозиторий ищите это2
последнюю версию библиотеки и добавил вgradle
илиmaven
В файле конфигурации проекта, а затем скомпилируйте проект.
Сгенерировано с помощью TFRecorder
из-за созданияTFRecord
При написании файлов часто приходится писать большой объем сложного кода, чтобы оптимизировать сложность кода,TensorFlow
Официально с открытым исходным кодомTensorFlow Recorder
проект (т.е.TFRecorder
) для более легкого созданияTFRecord
документ.
TFRecorder
Разрешить пользователям изPandas dataframe
илиCSV
Создать напрямуюTFRecords
файл без написания сложного кода. Это особенно удобно для обработки графических данных.TFRecorder
Прежде, чем генерировать крупномасштабныеTFRecord
Отформатируйте данные изображения, необходимо написать конвейер данных для загрузки изображения из хранилища и сериализации результата какTFRecord
формате, и теперь требуется всего несколько строк кода, чтобы сгенерировать изображение на основеTFRecord
документ. Пример кода выглядит следующим образом:
import pandas as pd
import tfrecorder
# From Pandas DataFrame
df = pd.read_csv('/path/to/data.csv')
df.tensorflow.to_tfr(output_dir='/my/output/path')
# From CSV
tfrecorder.create_tfrecords(
source='/path/to/data.csv',
output_dir='/my/output/path',
)
# From an image directory
tfrecorder.create_tfrecords(
source='/path/to/image_dir',
output_dir='/my/output/path',
)
БолееTFRecorder
Пожалуйста, обратитесь к его официальной документации для использования.
Чтение файла TFRecord
TensorFlow
Обеспечивает специальное чтениеTFRecord
документAPI
интерфейсtf.data.TFRecordDataset
, интерфейс может бытьTFRecord
Содержимое файла считывается вdataset
середина. Код выглядит следующим образом:
# Read TFRecord file to dataset.
raw_dataset = tf.data.TFRecordDataset(filename)
print(raw_dataset)
В настоящее времяdataset
Сохраняется в виде строки в сериализованном формате. Если ее нужно преобразовать в реальное значение, потребуются дальнейшие операции.
Вернуться к примеру
мы можем поставитьraw_dataset
Каждый элемент в сводится кtf.train.Example
, как правило, в небольшом диапазонеTFRecord
Данные используются для проверки, пример кода выглядит следующим образом:
for raw_record in raw_dataset.take(1):
example = tf.train.Example()
example.ParseFromString(raw_record.numpy())
print(example)
# or
example_proto = tf.train.Example.FromString(raw_record.numpy())
print(example_proto)
Использование модели для обучения
Чтобы использовать это во время обучения моделиdataset
, нам надоraw_dataset
Каждый элемент в разрешаетFeatureMap
, чтобы соответствоватьKeras
Вход и выход модели. Код выглядит следующим образом:
def _parse_function(example_proto):
# Create a description of the features.
feature_description = {
'feature0': tf.io.FixedLenFeature([], tf.int64, default_value=0),
'feature1': tf.io.FixedLenFeature([], tf.int64, default_value=0),
'feature2': tf.io.FixedLenFeature([], tf.string, default_value=''),
'feature3': tf.io.FixedLenFeature([], tf.float32, default_value=0.0),
}
# Parse the single input `tf.train.Example` proto using the dictionary above.
# return tf.io.parse_single_example(example_proto, feature_description)
# Parse the batch input tf.train.Example protos using the dictionary above.
return tf.io.parse_example(example_proto, feature_description)
# Print parsed dataset.
parsed_dataset = raw_dataset.map(_parse_function)
print(parsed_dataset)
# Print one element in parsed_dataset.
for parsed_record in parsed_dataset.take(1):
print(parsed_record)
используется здесьtf.io.parse_example
функция для разбора сериализованной строки в указанный тип данных, нам нужно подготовить заранееfeature_description
словарь, определяющийfeature
имя, длина (фиксированная/переменная), тип данных и значение по умолчанию для синтаксического анализа. Наконец мы звонимraw_dataset
изmap
метод применения аналитической функции кdataset
каждый элемент в .
В качестве альтернативы мы также можем использоватьtf.io.parse_single_example
функцию для анализа, но обратите внимание, что она не связана сtf.io.parse_example
Разница между первым подходит для анализа одного сериализованного элемента, а второй подходит дляbatch
анализ. существуетTensorFlow 数据输入的最佳实践
представлено в статьеdataset
векторизацияmap
операция, т.е.dataset
Подать заявку первымbatch
Конвертируйте, а затем применяйтеmap
Преобразование для повышения эффективности, поэтому рекомендуется использовать последнюю в качестве функции разбора сериализованных данных.
Наконец мы можемparsed_dataset
используется при обучении моделей. Пример кода выглядит следующим образом:
model.fit(parsed_dataset)
Примечание:label
данные должны бытьfeatures
данные там жеdataset
середина,TensorFlow
будет вводить и выводить в соответствии с модельюTensor
изname
идти сdataset
Получите соответствующие данные для обучения.