이제 구성 파일이 정의되었으므로 실제로 HDF5 데이터 세트를 빌드 해 보겠습니다. 새 파일을 열고 이름을 build_dogs_vs_cats.py로 지정하고 다음 코드를 삽입합니다.

2-12 행은 필수 Python 패키지를 가져옵니다. 프로젝트의 첫 번째 가져 오기로 프로젝트 구성 파일을 가져오고 싶습니다 (2 행). 이 방법은 취향의 문제이므로 파일에서 원하는 위치에 가져 오기를 자유롭게 배치하십시오. 또한 dogs_vs_cats_config의 이름을 단순히 config로 변경하여 코드를 작성할 때 덜 장황하게 만듭니다.
다음은 이전 장에서 보았던 import 입니다. 그러나 23 장에서 정의한 것과 동일한 HDF5DatasetWriter 인 6 행의 HDF5DatasetWriter에 주의를 기울이고 싶습니다.이 클래스는 디스크의 원시 이미지를 단일 직렬 파일로 압축하는 데 사용됩니다.
또한 주어진 작업에 걸리는 대략적인 시간을 측정 할 때 사용하는 간단한 유틸리티 라이브러리 인 progressbar 모듈을 다시 사용할 것입니다. 이 모듈은 딥러닝과는 전혀 관련이 없지만 대용량 데이터 세트의 경우 이미지 데이터 세트를 HDF5 형식으로 압축하는 데 몇 시간이 걸릴 수 있으므로 사용하는 것이 편리합니다.
다음으로 Kaggle Dogs vs. Cats 데이터 세트의 이미지 경로를 살펴 보겠습니다.

Dogs vs. Cats 데이터 세트에는 다음 예제 디렉토리 구조가 있습니다.

클래스 이름이 실제 파일 이름에 어떻게 내장되어 있는지 확인하십시오. 따라서 파일 경로의 파일 구성 요소, 구분 기호를 입력하고 클래스 이름을 추출합니다. 실제로 16 행과 17 행이 수행하는 일입니다. 데이터 세트의 모든 이미지에 대한 경로가 주어지면 이미지를 개별적으로 반복하고 파일 경로에서 라벨을 추출합니다.
이러한 코드 줄이 혼란스러우면 지금 수동으로 코드, 특히 os.path.sep 변수와 파일 경로 문자열에 사용 된 .split 함수를 사용하여 이러한 유틸리티가 어떻게 사용되는지 자세히 알아 보는 것이 좋습니다. 파일 경로를 조작합니다.
그런 다음 18 행과 19 행은 클래스 레이블을 인코딩합니다. Kaggle Dogs vs. Cats 프로젝트의 경우 훈련 분할, 유효성 검사 분할, 테스트 분할의 세 분할이 필요합니다. 다음 코드 블록은 이러한 각 분할 생성을 처리합니다.

23-26 행에서 입력 이미지와 레이블을 가져 와서 훈련 및 테스트 분할을 구성하는 데 사용합니다. 그러나 검증 세트를 생성하려면 30-33 행에서 또 다른 분할을 수행해야합니다. 검증 세트는 (거의 항상) 훈련 데이터에서 가져옵니다. 테스트 및 유효성 검사 분할의 크기는 NUM_TEST_IMAGES 및 NUM_VAL_IMAGES를 통해 제어되며, 각각은 구성 파일에 정의되어 있습니다.
이제 학습, 테스트 및 유효성 검사 분할이 있으므로이를 반복하고 각 데이터 세트의 이미지를 HDF5 파일에 효율적으로 쓸 수있는 간단한 목록을 만들어 보겠습니다.

38 행에서 훈련, 검증 및 테스트 변수를 포함하는 데이터 세트 목록을 정의합니다. 목록의 각 항목은 다음으로 구성된 4- 튜플입니다.
1. 스플릿 이름 (예 : 교육, 테스트 또는 유효성 검사).
2. 분할에 대한 각각의 이미지 경로.
3. 분할의 레이블.
4. 분할을위한 출력 HDF5 파일의 경로.
그런 다음 45 행에서 AspectAwarePreprocessor를 초기화하여 HDF5에 기록하기 전에 이미지의 크기를 256x 256 픽셀로 조정합니다 (이미지의 종횡비를 염두에 두어야 함). 각 채널의 평균 픽셀 강도를 저장하는 데 사용되는 46 행 R, G, B의 세 목록도 초기화합니다. 마지막으로 HDF5 데이터 세트를 구축 할 준비가 되었습니다.

49 행에서 데이터 세트 목록의 각 4- 튜플 값을 반복하기 시작합니다. 각 데이터 분할에 대해 HDF5DatasetWriter를 52행에 인스턴스화합니다. 여기서 출력 데이터 세트의 크기는 (len (paths), 256, 256, 3)이며, 이는 len (paths) 만큼 총 이미지가 있음을 의미합니다. 너비는 256 픽셀, 높이는 256 픽셀, 채널 3 개입니다.
54-58 행은 데이터 셋 생성 과정을 쉽게 모니터링 할 수 있도록 진행률 표시 줄을 초기화합니다. 다시 말하지만,이 코드 블록 (나머지 진행률 표시 줄 함수 호출과 함께)은 전적으로 선택 사항이므로 원하는 경우 주석 처리 할 수 있습니다. 다음으로 지정된 데이터 분할의 각 이미지를 writer로 기록해 보겠습니다.

61 행에서 데이터 분할의 각 개별 이미지와 해당 클래스 레이블을 반복하기 시작합니다. 63 행과 64 행은 디스크에서 이미지를 로드 한 다음 aspect-aware preprocessor를 적용하여 이미지 크기를 256×256 픽셀로 조정합니다.
train 데이터 분할을 검토하고 있는지 확인하기 위해 69 행을 확인하고, 그렇다면 Red, Green, Blue 채널 (70행)의 평균을 계산하고 71-73 번 라인의 각 목록을 업데이트합니다. RGB 채널의 평균 계산은 훈련 세트에 대해서만 수행되며 평균 빼기 정규화를 적용하려는 경우 필수 사항입니다.
76 행은 해당 이미지와 레이블을 HDF5DatasetWriter에 추가합니다. 데이터 분할의 모든 이미지가 HDF5 데이터 세트로 직렬화되면 81 행에서 writer를 닫습니다. 마지막 단계는 RGB 평균을 디스크에 직렬화하는 것입니다.

86 행은 훈련 세트의 모든 이미지에 대한 평균 RGB 값의 Python dictionary를 구성합니다. 각 개별 R, G, B에는 데이터 세트의 각 이미지에 대한 평균 채널이 포함되어 있습니다. 이 목록의 평균을 계산하면 목록의 모든 이미지에 대한 평균 픽셀 강도 값이 제공됩니다. 이 dictionary는 87-88 행에서 JSON 형식으로 디스크에 직렬화됩니다.
계속해서 Kaggle Dogs vs. Cats 데이터 세트를 HDF5 형식으로 직렬화하겠습니다. 터미널을 열고 다음 명령을 실행하십시오.

출력에서 볼 수 있듯이 각 훈련, 테스트 및 검증 분할에 대해 HDF5 파일이 생성되었습니다. 이 분할에는 가장 많은 데이터 (2m39s)가 포함되어 있으므로 훈련 분할 생성에 가장 오래 걸렸습니다. 테스트 및 유효성 검사 분할은 이러한 분할에 데이터가 더 적기 때문에 훨씬 더 적은 시간 (≈ 20 초)이 소요되었습니다. hdf5 디렉토리의 내용을 나열하여 디스크에서 이러한 각 출력 파일을 볼 수 있습니다

이러한 파일 크기를 보면 약간 놀랄 수 있습니다. 디스크에있는 원시 Kaggle Dogs vs. Cats 이미지는 595MB에 불과합니다. .hdf5 파일이 왜 그렇게 큰가요? train.hdf5 파일 만 31.45GB이고 test.hdf5 및 val.hdf5 파일은 거의 4GB입니다. 왜 그럴까요?
JPEG 및 PNG와 같은 원시 이미지 파일 형식은 데이터 압축 알고리즘을 적용하여 이미지 파일 크기를 작게 유지합니다. 그러나 우리는 모든 유형의 압축을 효과적으로 제거했으며 이미지를 원시 NumPy 배열 (즉, 비트 맵)로 저장하고 있습니다. 이러한 압축 부족으로 인해 스토리지 비용이 크게 증가하지만 이미지를 디코딩하는 데 프로세서 시간을 낭비 할 필요가 없기 때문에 교육 시간을 단축하는 데 도움이됩니다. 대신 HDF5 데이터 세트에서 직접 이미지에 액세스하고 이를 전처리 한 다음 전달할 수 있습니다. 우리 네트워크를 통해. RGB 평균 파일도 살펴 보겠습니다.

여기에서 빨간색 채널의 평균 픽셀 강도는 데이터 세트의 모든 이미지에서 124.96임을 알 수 있습니다. 파란색 채널의 평균은 106.13이고 녹색 채널은 평균 115.97입니다. 네트워크를 통과하기 전에 입력 이미지에서 이러한 RGB 평균값을 빼서 이미지를 정규화하는 새로운 이미지 전처리기를 구성 할 것입니다. 이는 정규화를 통해 데이터를 제로 평균을 중심으로 “중심화”할 수 있습니다. 일반적으로이 정규화를 통해 우리의 네트워크는 더 빨리 학습 할 수 있으며 더 크고 까다로운 데이터 세트에서 이러한 유형의 정규화 ([0,1] 스케일링 대신)를 사용합니다.
이 장에서는 원시 이미지를 심층 신경망 훈련에 적합한 HDF5 데이터 세트로 직렬화하는 방법을 배웠습니다. 교육이 I/O 지연으로 인해 디스크에있는 이미지 경로의 미니 배치에 액세스하는 것이 아니라 원시 이미지를 HDF5 파일로 직렬화 한 이유는 I/O 지연 때문입니다 – 디스크의 각 이미지를 읽기 위해 I/O 작업을 수행해야 합니다.
이 미묘한 최적화는 큰 문제처럼 보이지 않지만 I/O 지연은 딥 러닝 파이프 라인에서 큰 문제입니다. 훈련 프로세스는 이미 충분히 느리고 네트워크가 데이터에 액세스하는 것을 어렵게 만들면 더욱 악화될 뿐입니다.
반대로 모든 이미지를 효율적으로 압축 된 HDF5 파일로 직렬화하면 매우 빠른 어레이 슬라이스를 활용하여 미니 배치를 추출 할 수 있으므로 I/O 지연 시간을 크게 줄이고 교육 프로세스 속도를 높일 수 있습니다.
Keras 라이브러리를 사용하고 메모리에 맞지 않는 너무 큰 데이터 세트로 작업 할 때마다 먼저 데이터 세트를 HDF5 형식으로 직렬화하는 것을 고려해야합니다. 다음 장에서 (더 효율적인) 작업을 확인할 수 있으므로 네트워크 훈련이 더 쉬워질 것입니다.