이 라이브러리를 사용하면 Python에서 Tfrecord 파일을 효율적으로 읽고 읽을 수 있습니다. 이 라이브러리는 또한 Pytorch 용 Tfrecord 파일의 iterabledataset 리더를 제공합니다. 현재 압축되지 않고 압축되지 않은 GZIP Tfrecord가 지원됩니다.
pip3 install 'tfrecord[torch]'
각 tfrecord 파일에 대한 인덱스 파일을 작성하는 것이 좋습니다. 여러 작업자를 사용할 때 인덱스 파일이 제공되어야합니다. 그렇지 않으면 로더가 중복 레코드를 반환 할 수 있습니다. 이 유틸리티 프로그램을 사용하여 개별 tfrecord 파일에 대한 인덱스 파일을 만들 수 있습니다.
python3 -m tfrecord.tools.tfrecord2idx <tfrecord path> <index path>
" .tfidnex"파일을 모두 만들려면 " .tfrecord"파일이 실행됩니다.
tfrecord2idx <data dir>
tfrecorddataset을 사용하여 Pytorch에서 tfrecord 파일을 읽으십시오.
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" ]) 시퀀스 검사원은 각각의 읽기/쓰기 기능이 시퀀스 표기로 취급되는 추가 인수 (읽기를위한 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 ()시퀀스면에서 읽는 것은 두 가지 요소를 포함하는 튜플을 예정합니다.
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 )