تتيح هذه المكتبة قراءة وكتابة ملفات tfrecord بكفاءة في بيثون. توفر المكتبة أيضًا قارئ iterabledataset لملفات tfrecord لـ pytorch. يتم دعم GZIP tfrecords غير مضغوطة ومضغوط حاليًا.
pip3 install 'tfrecord[torch]'
يوصى بإنشاء ملف فهرس لكل ملف tfrecord. يجب توفير ملف الفهرس عند استخدام العديد من العمال ، وإلا يجوز أن يقوم المحمل بإرجاع السجلات المكررة. يمكنك إنشاء ملف فهرس لملف tfrecord فردي مع برنامج الأداة المساعدة هذا:
python3 -m tfrecord.tools.tfrecord2idx <tfrecord path> <index path>
لإنشاء ملفات ".tfidnex" للجميع " .tfrecord" في دليل دليل:
tfrecord2idx <data dir>
استخدم tfrecorddataset لقراءة ملفات tfrecord في pytorch.
import torch
from tfrecord . torch . dataset import TFRecordDataset
tfrecord_path = "/tmp/data.tfrecord"
index_path = None
description = { "image" : "byte" , "label" : "float" }
dataset = TFRecordDataset ( tfrecord_path , index_path , description )
loader = torch . utils . data . DataLoader ( dataset , batch_size = 32 )
data = next ( iter ( loader ))
print ( data )استخدم multitfrecordDataset لقراءة ملفات tfrecord متعددة. عينات الفئة هذه من ملفات tfrecord المعطاة مع احتمال معين.
import torch
from tfrecord . torch . dataset import MultiTFRecordDataset
tfrecord_pattern = "/tmp/{}.tfrecord"
index_pattern = "/tmp/{}.index"
splits = {
"dataset1" : 0.8 ,
"dataset2" : 0.2 ,
}
description = { "image" : "byte" , "label" : "int" }
dataset = MultiTFRecordDataset ( tfrecord_pattern , index_pattern , splits , description )
loader = torch . utils . data . DataLoader ( dataset , batch_size = 32 )
data = next ( iter ( loader ))
print ( data ) بشكل افتراضي ، تعتبر MultiTFRecordDataset غير محدودة ، مما يعني أنه يعين البيانات إلى الأبد. يمكنك جعلها محدودة من خلال توفير العلم المناسب
dataset = MultiTFRecordDataset(..., infinite=False)
كل من TfreCordDataset و MultitFreCordDataset تلقائيًا خلط البيانات عند توفير حجم قائمة انتظار.
dataset = TFRecordDataset(..., shuffle_queue_size=1024)
يمكنك تمرير وظيفة اختياريًا كوسيطة transform لإجراء معالجة ما بعد الميزات قبل العودة. يمكن استخدام هذا على سبيل المثال لفك تشفير الصور أو تطبيع الألوان إلى تسلسل طول متغير نطاق أو لوحة.
import tfrecord
import cv2
def decode_image ( features ):
# get BGR image from bytes
features [ "image" ] = cv2 . imdecode ( features [ "image" ], - 1 )
return features
description = {
"image" : "bytes" ,
}
dataset = tfrecord . torch . TFRecordDataset ( "/tmp/data.tfrecord" ,
index_path = None ,
description = description ,
transform = decode_image )
data = next ( iter ( dataset ))
print ( data ) import tfrecord
writer = tfrecord . TFRecordWriter ( "/tmp/data.tfrecord" )
writer . write ({
"image" : ( image_bytes , "byte" ),
"label" : ( label , "float" ),
"index" : ( index , "int" )
})
writer . close () import tfrecord
loader = tfrecord . tfrecord_loader ( "/tmp/data.tfrecord" , None , {
"image" : "byte" ,
"label" : "float" ,
"index" : "int"
})
for record in loader :
print ( record [ "label" ]) يمكن قراءة SequenceExamples وكتابتها باستخدام نفس الأساليب الموضحة أعلاه مع وسيطة إضافية ( sequence_description للقراءة sequence_datum للكتابة) والتي تسبب وظائف القراءة/الكتابة ذات الصلة بمعالجة البيانات كمتسلسل على سبيل المثال.
import tfrecord
writer = tfrecord . TFRecordWriter ( "/tmp/data.tfrecord" )
writer . write ({ 'length' : ( 3 , 'int' ), 'label' : ( 1 , 'int' )},
{ 'tokens' : ([[ 0 , 0 , 1 ], [ 0 , 1 , 0 ], [ 1 , 0 , 0 ]], 'int' ), 'seq_labels' : ([ 0 , 1 , 1 ], 'int' )})
writer . write ({ 'length' : ( 3 , 'int' ), 'label' : ( 1 , 'int' )},
{ 'tokens' : ([[ 0 , 0 , 1 ], [ 1 , 0 , 0 ]], 'int' ), 'seq_labels' : ([ 0 , 1 ], 'int' )})
writer . close ()القراءة من تسلسل مثال yeilds tuple تحتوي على عنصرين.
import tfrecord
context_description = { "length" : "int" , "label" : "int" }
sequence_description = { "tokens" : "int" , "seq_labels" : "int" }
loader = tfrecord . tfrecord_loader ( "/tmp/data.tfrecord" , None ,
context_description ,
sequence_description = sequence_description )
for context , sequence_feats in loader :
print ( context [ "label" ])
print ( sequence_feats [ "seq_labels" ]) كما هو موضح في القسم حول Transforming Input ، يمكن للمرء أن يمرر وظيفة كوسيطة transform لإجراء معالجة ما بعد الميزات. يجب استخدام هذا خاصة بالنسبة لميزات التسلسل لأن هذه تسلسل طول متغير ويجب أن يتم تجهيزها قبل التثبيت.
import torch
import numpy as np
from tfrecord . torch . dataset import TFRecordDataset
PAD_WIDTH = 5
def pad_sequence_feats ( data ):
context , features = data
for k , v in features . items ():
features [ k ] = np . pad ( v , (( 0 , PAD_WIDTH - len ( v )), ( 0 , 0 )), 'constant' )
return ( context , features )
context_description = { "length" : "int" , "label" : "int" }
sequence_description = { "tokens" : "int " , "seq_labels" : "int" }
dataset = TFRecordDataset ( "/tmp/data.tfrecord" ,
index_path = None ,
description = context_description ,
transform = pad_sequence_feats ,
sequence_description = sequence_description )
loader = torch . utils . data . DataLoader ( dataset , batch_size = 32 )
data = next ( iter ( loader ))
print ( data ) بدلاً من ذلك ، يمكنك اختيار تنفيذ collate_fn مخصص من أجل تجميع الدفعة ، على سبيل المثال ، لأداء الحشوة الديناميكية.
import torch
import numpy as np
from tfrecord . torch . dataset import TFRecordDataset
def collate_fn ( batch ):
from torch . utils . data . _utils import collate
from torch . nn . utils import rnn
context , feats = zip ( * batch )
feats_ = { k : [ torch . Tensor ( d [ k ]) for d in feats ] for k in feats [ 0 ]}
return ( collate . default_collate ( context ),
{ k : rnn . pad_sequence ( f , True ) for ( k , f ) in feats_ . items ()})
context_description = { "length" : "int" , "label" : "int" }
sequence_description = { "tokens" : "int " , "seq_labels" : "int" }
dataset = TFRecordDataset ( "/tmp/data.tfrecord" ,
index_path = None ,
description = context_description ,
transform = pad_sequence_feats ,
sequence_description = sequence_description )
loader = torch . utils . data . DataLoader ( dataset , batch_size = 32 , collate_fn = collate_fn )
data = next ( iter ( loader ))
print ( data )