학습 데이터 TFRecord 포멧으로 변환하기

2023. 9. 6.Tech

tensorflow에서 이미지 데이터를 이용해 모델을 학습시키는 경우, 데이터를 주로 ‘generator’ 또는 TFRecord 포멧으로 변환하여 로드 하게 됩니다.

이와 관련하여, 해당 포스트에서는 tfrecord 포멧으로 변환하는 방법에대해 다룰 예정이며 아래의 내용을 포함하고 있습니다.

  • tfrecord 포멧이란?
  • tfrecord 포멧으로 변환하는 방법
  • tfrecord 파일 로드
  • 데이터셋 로드 속도 비교

1) tfrecord 포멧이란?

tensorflow 공식 홈페이지를 보면 TFrecord 형식을 “이진 레코드 시퀀스를 저장하기 위한 간단한 형식입니다.” 라고 설명하고 있습니다.

설명이 어렵지만, 간단하게 tfrecord 포맷은 “tensorflow에서 사용할 데이터(학습, 테스트 등)를 저장하기 위한 데이터 포멧”이라고 생각하면 될 것 같습니다.

즉, tfrecord 포멧으로 저장된 파일을 로드하여 바로 학습에 사용할 수 있습니다. 예를들어, 이미지 분류 모델을 학습시키는 경우 데이터는 주로 폴더의 형태로 관리되고 모델을 학습시키기 위해서는 이미지 파일을 읽고, 해당 이미지 파일의 라벨을 로드하는 등 데이터 처리에 번거로움이 있습니다.

그러나 tfrecord 파일 포멧을 사용하게 되면 이러한 번거로움을 해결 할 수 있습니다. 구체적인 방법은 아래의 소스코드 등을 통해 설명 하겠습니다.

2) 데이터셋 다운로드

우선, 데이터셋을 다운로드 합니다. 다운로드를 완료 후 압축을 해제하면 아래와 같은 폴더 구조를 확인할 수 있습니다.

다운로드한 데이터셋 폴더 구조

해당 데이터셋은 꽃 이미지 데이터 셋으로, tensorflow에서 제공하는 샘플 데이터 셋 입니다.

먼저, 데이터셋을 탐색해 보겠습니다. 다운로드 한 데이터 셋은 이미지 분류모델 학습을 위한 데이터 셋 입니다. 따라서, 디렉토리 구조를 보면 폴더명은 꽃 이름(분류 라벨)으로 되어있고 해당 폴더에 아래와 같은 꽃 이미지들이 저장되어 있습니다.

총 5개의 라벨로 구성되어있고 전체 이미지는 3,670장이 저장되어 있는 것을 확인 할 수 있습니다.

다운로드 한 데이터 셋 일부 시각화 결과

이제, 데이터셋을 다운로드를 완료 했으니 해당 데이터셋을 통해 tfrecord 포멧 파일을 만들고 모델 학습까지의 과정을 소개하도록 하겠습니다.

3) TFRecord 포멧으로 변환

tfrecord 포맷은 데이터를 저장하기 위한 데이터 포멧 이라고 하였습니다. 앞서 다운로드 한 데이터셋은 이미지 분류 모델을 위한 데이터로, 모델을 학습하기 위해서는 이미지와 클래스 정보가 필요합니다. 따라서, 이미지 정보와 이미지에 대한 라벨정보를 tfrecord 포멧 파일로 만들어 보도록 하겠습니다.

 

위에 첨부된 코드는 앞서 다운로드한 데이터셋을 로드하여 tfrecord 포멧으로 변경후 tfrecord 파일로 저장하는 코드입니다.

라인 별로 코드의 내용을 간략하게 살펴보면,

  • line 1~3 : 패키지 로드
  • line 5~16 : 학습에 필요한 데이터 정보를 저장 (여기서는 이미지 정보, 라벨 인덱스 정보, 라벨 이름을 저장)

[참고]

feature를 정의하는 경우 데이터 타입에 맞게 tf.train.Example의 데이터 유형에 매핑될 수 있도록 정의해야 합니다.

- string, byte 타입의 경우 tf.train.ByteList

- float, double 타입의 경우 tf.train.FloatList

- bool, enum, int32, uint32, int64, uint64 타입의 경우 tf.train.Int64List

즉, 위의 경우 이미지 정보는 byte 타입에 해당하므로 tf.train.ByteList로, label 인덱스는 int형에 해당하므로, tf.train.Int64List, label 명의 경우 str 타입에 해당하므로 tf.train.ByteList로 매핑하였습니다.

  • line 18~41 : 데이터셋을 로드하여 tfrecord 포멧으로 변환하는 코드

위와 같이 소스코드를 실행하면 ‘train.tfrecord’ 파일이 저장되는 것을 확인할 수 있을 것입니다.

4) tfrecord 데이터 읽기 & 로드

앞서, 데이터셋을 tfrecord 포멧으로 변환하여 ‘train.tfrecord’ 파일을 생성하였습니다. 이는 tf.train.Example 객체를 만든것 입니다.

이제 학습에 사용할 수 있도록 tf.train.Example 객체에서 tf.data.Dataset으로 변환하도록 하겠습니다. 변환하는 과정은 feature parsing, 모델에 맞는 데이터 전처리 순, 배치 데이터 생성 순 으로 처리 됩니다.

자세한 과정은 아래의 코드를 참조해주시기 바랍니다.

 

소스코드를 살펴보면,

  • line 11~19에 정의된 ‘parse_tfrecord’ 함수를 통해서 tfrecord 파일에 저장된 정보가(byte 타입의 이미지, 라벨 인덱스) parsing 됩니다.
  • line 22~30에 정의된 data_preprocessing 함수에 의해 분류기 학습이 가능한 데이터의 형태로 전처리 됩니다. (이미지 크기를 리사이징)
  • 최종적으로, line 53~56과 같이 데이터의 배치를 생성해주고 prefetch를 통해 데이터 로드시간을 최적화 합니다.

prefetch 함수관련 참조

prefetch 함수는 데이터가 소비되는 시간과 데이터가 생성되는 시간 간의 의존성을 줄일 수 있습니다. 특히, 이 변환은 백그라운드 스레드와 내부 버퍼를 사용하여 요청된 시간 전에 입력 데이터셋에서 요소를 가져옵니다.

또한, 아래의 코드를 추가하여 위의 소스코드에 추가하여 실행하면 train_dataset에 저장된 정보를 시각화 하여 확인 할 수 있습니다.

 

5) 데이터 로드 속도 비교

서론에 tensorflow의 경우 주로 generator 또는 tfrecord 포멧으로 데이터를 로드한다고 설명하였습니다. 그럼, 두 가지 방법의 데이터 로드 속도를 비교해 보도록 하겠습니다.

해당 실험은 아래와 같은 환경에서 수행되었습니다

  • CPU : Intel(R) Xeon(R) Silver 4214 CPU @ 2.20GHz, 24 CORE
  • GPU : Quadro RTX 5000
  • Memory : 32G
 

위의 소스코드 실행 결과는 아래와 같습니다.

# tfrecord 데이터셋 로딩 결과
1 epoch from tfrecord dataset : 1.643190622329712
# generator를 통한 데이터셋 로딩 결과
1 epoch from generator dataset : 11.05495572090149

실험결과 tfrecord를 통한 데이터셋 로딩 속도가 generator 보다 약 10배 이상의 빠른 속도를 보이는 것으로 확인 되었습니다.

6) 마무리

본 블로그에서는 tfrecord 포멧의 데이터 셋을 생성하는 방법에 대해서 소개하였습니다.

tensorflow의 경우 일반적으로 generator를 통해서 데이터를 주로 로드하게 되는데 이는 tfrecord 포멧에 비하여 데이터 처리 속도가 느리다는 단점이 있습니다. 해당 블로그에서 실험한 결과에 따르면 약 10배 가까이 차이나는 것으로 확인 되었습니다.

따라서, tensorflow를 통해 데이터를 로드하는경우 tfrecord 포멧을 사용할 것을 권장드립니다.

 

 

 

케이뱅크와 함께 하고 싶다면 🚀