Tensorflow 데이터 예비 처리 tf.data.TFRecordDataset-TFRecords 상세 설명\TFRecords 이미지 예비 처리

목차
개술
4.567917.2.예비 처리 데이터상수 정의
가 져 오기 라 이브 러 리
  • 2.3,train.txt 파일 에서 그림 읽 기-태그 쌍
  • 4.567917.2.4.그림 을 미리 처리 하고 저장 합 니 다2.5,호출 main 함수4.567917.3.예비 처리 후의 데 이 터 를 읽 습 니 다가 져 오기 라 이브 러 리3.2,정의 TFRecordDataset데 이 터 를 성공 적 으로 읽 었 는 지 검증 합 니 다4.567917.3.3,tensorflow 모델 에서 사용3.5,Keras 에서 사용1.개술
    Tensoflow 에서 예비 처리 데 이 터 는 tf.data.dataset 외 에 도 TFRecords 를 사용 할 수 있 습 니 다.tf.data.dataset 에 비해 장단 점 은 다음 과 같다.
    4.567917.훈련 할 때 데이터 예비 처 리 를 절약 하 는 계산 자원.TFRecords 를 사용 할 때 는 원본 데 이 터 를 처리 한 후 특정한 형식 으로 TFRecords 파일 로 저장 하 며 훈련 은 데 이 터 를 간단하게 꺼 내 훈련 할 뿐 훈련 할 때 상당 한 계산 자원 을 절약 할 수 있다
    4.567917.예비 처리 데이터 의 논 리 는 매우 복잡 할 수 있다.TFRecords 를 사용 할 때 데이터 예비 처 리 는 임의의 python 코드 를 사용 하여 완성 할 수 있 으 며,Tensorflow 가 미리 정 의 된 조작 에 얽 매 이지 않 아 도 되 며,예비 처리 데이터 에 상당 한 유연성 을 제공 하여 예비 처리 데이터 의 논 리 는 매우 복잡 할 수 있다
    4.567917.훈련 할 때 사용 하 는 메모리 가 더욱 작다.이 점 은 복잡 한 데이터 전처리 가 필요 없 기 때문에 사용 하 는 메모리 가 더 작 을 수 있 습 니 다
    4.567917.처리 후의 데 이 터 는 원시 데이터 보다 몇 배 클 수 있 습 니 다.이 점 은 이미지 데 이 터 를 대상 으로 하 는 것 입 니 다.그림 은 압축 되 어 있 기 때문에 이미지 원본 파일 이 비교적 작 습 니 다.사전 처리 가 끝 난 후 픽 셀 값 은 부동 소수점 이나 정수 로 저 장 됩 니 다.따라서 이미지 원본 이미지 데이터 에 비해 처리 후의 데 이 터 는 원본 데이터 보다 몇 배 나 크다
    본 고 는 실제 적 인 예 에서 출발 하여 TFRecords 를 어떻게 사용 하 는 지 설명 하고 다음 과 같은 몇 가지 부분 으로 나 눌 것 이다.두 번 째 절 은 데 이 터 를 어떻게 미리 처리 하 는 지(이미지 처 리 를 예 로 들 어)하고 데 이 터 를 TFRecords 파일 로 저장 하 는 지 설명 한다.세 번 째 부분 에 서 는 TFRecords 파일 을 읽 고 Tensoflow 와 Keras 에서 이 데 이 터 를 어떻게 사용 하 는 지 설명 합 니 다.
    참조 링크(공식 링크 를 많이 보 는 것 이 왕도):
  • Using TFRecords and TF Examples。

  • 데 이 터 를 가 져 옵 니 다
  • tf.data.TFRecordDataset。

  • 2.예비 처리 데이터
    내 프로젝트 에서 데이터 전처리 의 요 구 는 다음 과 같다.먼저 텍스트 파일 에서 이미지 경로 와 탭 을 읽 는 것 이다.그리고 그림 경로 에 따라 그림 을 읽 고 픽 셀 값 의 범 위 를[0,255]에서[-1.0,1.0]으로 확대 합 니 다.그리고 처 리 된 데이터 와 해당 하 는 탭 을 TFRecords 파일 에 저장 합 니 다.상기 텍스트 파일 의 이름 은 train.txt 입 니 다.한 줄 은 그림 견본 을 대표 하고 그림 경로 와 해당 하 는 태그 로 구성 되 며 일부 몇 줄 은 다음 과 같 습 니 다.
    data/M-PIE/test/001/001_01_01_051_09.png 0
    data/M-PIE/test/001/001_01_01_051_10.png 0
    data/M-PIE/test/002/002_01_01_051_19.png 1
    data/M-PIE/test/002/002_01_01_051_09.png 1
    data/M-PIE/test/003/003_01_01_051_14.png 2
    data/M-PIE/test/003/003_01_01_051_03.png 2
    data/M-PIE/test/004/004_01_01_051_05.png 3
    data/M-PIE/test/004/004_01_01_051_06.png 3
    ...
    

    2.1 상수 정의
    이 부분 은 주로 일부 상수 들 을 globals.py 파일 에 정의 하여 곳곳에 상수 가 없 도록 하고 나중에 수정 하기 도 편리 합 니 다.
    # coding=utf-8
    #   python3
    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    
    import os
    import random
    import numpy as np
    import tensorflow as tf
    
    # -----------------------   --------------------------
    #     ,     
    SEED = 1213
    
    #          ,             
    NUM_CLASSES = 285  
    
    #          
    IMAGE_SHAPE = (227, 227, 3)
    #             
    IMAGE_SIZE = IMAGE_SHAPE[0] * IMAGE_SHAPE[1] * IMAGE_SHAPE[2]
    
    #              
    IMAGE_DEPTH = 255
    
    #      
    NUM_TRAIN_EPOCH = 400
    #    batch size
    TRAIN_BATCH_SIZE = 128
    
    #       -         
    TRAIN_LIST = 'data/train.txt'
    #              
    TRAIN_TFRECORDS = 'data/train.tfrecords'
    
    #       -         
    VAL_LIST = 'data/test.txt'
    #              
    VAL_TFRECORDS = 'data/test.tfrecords'
    
    # ------------------------------------------------------
    
    def set_seed():
        """
                ,             ,        。
        """
        os.environ['PYTHONHASHSEED'] = str(SEED)
        np.random.seed(seed=SEED)
        tf.set_random_seed(seed=SEED)
        random.seed(SEED)
    

    2.2 도입 라 이브 러 리
    여기 서부 터 코드 는 모두 preprocess.py 에서 이 루어 지고 모든 코드 는 100 줄 이 안 됩 니 다.
    # coding=utf-8
    #       python2     python3
    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    
    import numpy as np
    import tensorflow as tf
    import cv2
    
    import globals as _g
    #        
    _g.set_seed()
    

    2.3,train.txt 파일 에서 그림 읽 기-태그 쌍
    이 부분 코드 는 매우 간단 합 니 다.numpy 의 함 수 를 사용 하면 완성 할 수 있 고 오류 가 발생 하지 않 습 니 다.
    def main(list_name, record_file_name):
        """
                        tfrecords    
        :param list_name:     -          
        :param record_file_name: tfrecords     
        """
        #     -   ,        ((path1,label1),(path2, label2), ...)
        lists_and_labels = np.loadtxt(list_name, dtype=str).tolist()
        #    -      ,     
        np.random.shuffle(lists_and_labels)
    

    2.4 그림 을 미리 처리 하고 저장
    이 부분 코드 는 main 함수 의 일부분 입 니 다.아주 간단 합 니 다.먼저 코드 를 올 립 니 다.
    	#     TFRecordWriter,   TFRecords  
        writer = tf.python_io.TFRecordWriter(record_file_name)
    
        for file_name, label in lists_and_labels:
            #   read_image          ,    numpy  
            img = read_image(file_name)
            #  img shape _g.IMAGE_SHAPE   [_g.IMAGE_SIZE, ]
            img_reshape = np.reshape(img, [_g.IMAGE_SIZE, ])
            print(file_name, img.shape, img_reshape.shape)
    
            #        ,                ,   
            #       ,         。
            feature = {
                'label': tf.train.Feature(int64_list=tf.train.Int64List(value=[int(label)])),
                'image_raw': tf.train.Feature(float_list=tf.train.FloatList(value=img_reshape.tolist()))
            }
    
            #     Example
            example = tf.train.Example(features=tf.train.Features(feature=feature))
    		 #  example      
            writer.write(example.SerializeToString())
    
        writer.close()
    

    read 에 대하 여image 위 코드 에 사 용 된 OpenCV 라 이브 러 리 를 사용 하여 그림 을 읽 은 다음 numpy 를 사용 하여 데이터 형식 변환 을 완성 합 니 다.값 의 범 위 를[0,255]에서[-1.0,1.0]으로 확대 합 니 다.코드 는 다음 과 같 습 니 다.
    def read_image(file_name):
        """
                。
        :param file_name:      
        :return: numpy  ,shape _g.IMAGE_SHAPE
        """
        #     ,img numpy  ,dtype=np.uint8
        img = cv2.imread(file_name, cv2.IMREAD_UNCHANGED)
        #   img   ,          
        img = cv2.resize(img, _g.IMAGE_SHAPE[0:2])
        #   img     
        img = img.astype(dtype=np.float32)
        #         [0, 255]   [-1.0, 1.0]
        img -= _g.IMAGE_DEPTH / 2
        img /= _g.IMAGE_DEPTH / 2
        return img
    

    tf.train.Feature 에 관 한 tf.Example 은 많은 tf.train.Feature 로 구성 되 어 있 습 니 다(이렇게 이해 할 수 있 습 니 다).tf.train.Feature 는 다음 세 가지 유형의 데 이 터 를 받 을 수 있 고 다른 유형의 데 이 터 는 기본적으로 이 세 가지 데이터 로 변환 할 수 있 습 니 다.
  • bytes_list(string,byte)
  • float_list (float32,float64)
  • int64_list(bool,enum,int32, uint32,int64, uint64)

  • 표준 형식 을 tf.train.Feature 호 환 으로 변환 하기 위해 다음 함 수 를 사용 할 수 있 습 니 다.
    def _bytes_feature(value):
      """Returns a bytes_list from a string / byte."""
      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]))
    

    설명 할 것 은 tf.train.****List 의 value 매개 변 수 는 list 입 니 다.위 함수 의 예 를 사용 합 니 다:
    print(_bytes_feature('test_string'))
    print(_bytes_feature(bytes('test_bytes')))
    print(_float_feature(np.exp(1)))
    print(_int64_feature(True))
    print(_int64_feature(1))
    

    글 에서 저 는 label 을 int 64 로 저장 합 니 다.list;그림 데 이 터 를 저장 하 는 것 은 float 를 사용 합 니 다.list,float 를 사용 하 는 이유list,하 나 는 읽 을 때의 코드 를 더욱 간단하게 하기 위해 서 입 니 다.다른 하 나 는 읽 을 때의 CPU 자원 을 절약 하 는 것 입 니 다.파일 이 차지 하 는 공간 이 비교적 크다 는 단점 이 있 습 니 다.
    2.5.main 함수 호출
    훈련 집합 과 검증 집합 에 main 함 수 를 호출 하여 데이터 예비 처 리 를 완료 합 니 다:
    if __name__ == '__main__':
        main(_g.TRAIN_LIST, _g.TRAIN_TFRECORDS)
        main(_g.VAL_LIST, _g.VAL_TFRECORDS)
    

    이로써 데이터 의 예비 처 리 는 완성 되 었 다.
    3.예비 처리 후의 데 이 터 를 읽 습 니 다.
    이 부분 코드 는 tf.data.TFRecordDataset 을 사용 하여 tfrecords 파일 을 읽 는 방법 을 보 여 줍 니 다.TFRecordDataset 를 사용 하면 tensor flow 코드 로 쓴 모델 의 입력 도 가능 하고 keras 모델 로 입력 할 수도 있어 서 매우 기 쁩 니 다.tfrecords 파일 을 읽 는 다른 코드 도 있 으 니 더 이상 말 하지 않 겠 습 니 다.이 부분의 코드 는 inputs 에 구현 되 었 습 니 다.tfrecords.py 중.
    3.1 도입 라 이브 러 리
    # coding=utf-8
    #   python3
    from __future__ import absolute_import
    from __future__ import division
    from __future__ import print_function
    
    import numpy as np
    import multiprocessing as mt
    import tensorflow as tf
    import cv2
    import globals as _g
    
    _g.set_seed()
    

    3.2 TFRecordDataset 정의
    TFRecordDataset 는 tf.data.dataset 와 매우 비슷 합 니 다.여기 서 너무 많은 논술 을 하지 않 습 니 다.함수 에 대한 설명 은 제 다른 블 로그 tf.data.dataset 이미지 의 예비 처리 상세 한 두 번 째 부분 을 참조 할 수 있 습 니 다.
    def prepare_dataset(record_name, list_name):
        """
         record_name   TFRecords  ,     dataset
        :param record_name: TFRecords    
        :param list_name:  record_name      -       
        """
        #   TFRecordDataset
        dataset = tf.data.TFRecordDataset([record_name])
        #    dataset       _parse_function   TFRecords  
        dataset = dataset.map(_parse_function, mt.cpu_count())
        #   batch size  ,    。
        dataset = dataset.batch(_g.TRAIN_BATCH_SIZE)
        #        
        dataset = dataset.repeat()
        #   dataset          
        return dataset, compute_steps(list_name)
    

    에 대하 여parse_function _parse_function 은 TFRecords 를 해석 하 는 함수 로 다음 과 같이 실 현 됩 니 다.
    def _parse_function(record):
        #         ,  TFRecords         
        features = {
            'label': tf.FixedLenFeature([], tf.int64, default_value=0),
            'image_raw': tf.FixedLenFeature([_g.IMAGE_SIZE, ], tf.float32,)
        }
    
        #              (      Example)
        example = tf.parse_single_example(record, features)
    
        #  image shape [_g.IMAGE_SIZE, ]   _g.IMAGE_SHAPE
        image = tf.reshape(example['image_raw'], _g.IMAGE_SHAPE)
    
        #     dataset  keras ,model.fit      ,     one_hot  
        #  tensorflow ,       ,      example['label']。
        one_hot_label = tf.one_hot(example['label'], _g.NUM_CLASSES)
    
        return image, one_hot_label
    

    tf.Fixed LenFeature 의 첫 번 째 매개 변 수 는 특징 적 인 길이(요소 의 개수)입 니 다.하나의 정수 만 있 으 면[],뒤의 default 를 직접 전달 합 니 다.value 는 0 으로 설정 할 수 있 습 니 다.하나의 list 라면 많은 수가 있 습 니 다.첫 번 째 매개 변 수 를 이 특징의 길이 로 지정 해 야 합 니 다.(이 길 이 는 2.4 절 에 저 장 된 데이터 의 개수 와 같 아야 합 니 다),defaultvalue 는 설정 하지 않 는 것 을 권장 합 니 다.두 번 째 매개 변 수 는 특징 적 인 유형 입 니 다.
    compute 에 대하 여steps compute_steps 의 역할 은 한 라운드(one epoch)를 훈련 하 는 데 몇 걸음(steps)이 필요 합 니까?steps 계산 은 간단 합 니 다.recordname 대응 하 는 listname 은 몇 개의 견본 을 포함 하고 있 습 니까?
    def compute_steps(list_name):
        #        -   
        lists_and_labels = np.loadtxt(list_name, dtype=str).tolist()
    	#   batch size     
        return np.ceil(len(list(lists_and_labels)) / _g.TRAIN_BATCH_SIZE).astype(np.int32)
    

    3.3 데 이 터 를 성공 적 으로 읽 었 는 지 검증
    예 처리 가 정확 한 지 검증 하 는 방식 이 비교적 간단 하 다.전체적인 사고방식 은 데이터 세트 에서 이미지 와 라벨 을 가 져 온 다음 에 이미 지 를 저장 해서 맞 는 지 확인 하 는 것 이다.
    def save_image(file_name, image):
        """
          image file_name     
        """
        #         [-1.0, 1.0]     [0, 255]
        image *= _g.IMAGE_DEPTH / 2
        image += _g.IMAGE_DEPTH / 2
        #     
        image = image.astype(dtype=np.uint8)
        #     
        cv2.imwrite(file_name, image)
        
    def inputs_test():
        dataset, steps = prepare_dataset(_g.TRAIN_TFRECORDS, _g.TRAIN_LIST)
    
        print('shapes:', dataset.output_shapes)
        print('types:', dataset.output_types)
        print('steps: ', steps)
    
        next_op = dataset.make_one_shot_iterator().get_next()
        with tf.Session() as sess:
            for i in range(10):
                image, label = sess.run(next_op)
                print(image.shape, label.shape)
                save_image('logs/%d.png' % i, image[0])
    

    3.3 tensorflow 모델 에서 사용
    데이터 세트 에서 데 이 터 를 꺼 내 서 sess.run 의 feed 로 생각 합 니 다.dict 의 인자:
    import inputs_tfrecords
    ...
    
    def train():
        #    
        dataset, steps = inputs_tfrecords.prepare_dataset(_g.TRAIN_TFRECORDS, _g.TRAIN_LIST)
        #    
        val_dataset, val_steps = inputs_tfrecords.prepare_dataset(_g.VAL_TFRECORDS, _g.VAL_LIST)
    
        print('shapes:', dataset.output_shapes)
        print('types:', dataset.output_types)
        print('steps: ', steps)
    
        #   shape
        shape = _g.IMAGE_SHAPE[:]
        shape.insert(0, _g.TRAIN_BATCH_SIZE)
        #   placeholder
        img = tf.placeholder(shape=shape, name='image')
        lab = tf.placeholder(shape=[_g.TRAIN_BATCH_SIZE, ], name='label')
        #       
        train_op = ...
    
    
        #   
        next_op = dataset.make_one_shot_iterator().get_next()
        with tf.Session() as sess:
            for i in range(steps):
                image, label = sess.run(next_op)
                print(image.shape, label.shape)
                sess.run([train_op], feed_dict={'image': image, 'label': label})
                ...
    

    3.5,Keras 에서 사용
    그것 은 정말 간단 하 다.
    import inputs_tfrecords
    ...
    
    def train():
        #    
        dataset, steps = inputs_tfrecords.prepare_dataset(_g.TRAIN_TFRECORDS, _g.TRAIN_LIST)
        #    
        val_dataset, val_steps = inputs_tfrecords.prepare_dataset(_g.VAL_TFRECORDS, _g.VAL_LIST)
    
        print('shapes:', dataset.output_shapes)
        print('types:', dataset.output_types)
        print('steps: ', steps)
    
        #     
        model = tf.keras.Sequential()
        ...
        #   
        model.fit(train_dataset, epochs=_g.NUM_TRAIN_EPOCH, steps_per_epoch=train_steps,
                  validation_data=val_dataset, validation_steps=val_steps)
    

    tensorflow 에서 keras 를 어떻게 사용 하 는 지 에 대해 서 는 참고 할 수 있 습 니 다.
    Tensorflow keras 입문 강좌
  • Keras mnist 핸드폰 디지털 식별 기반-Keras 권 적 신경 네트워크 입문 강좌
  • 좋은 웹페이지 즐겨찾기