VGG16 (또는 다른 CNN)을 기능 추출기로 만들기 전에 먼저 약간의 인프라를 개발해야합니다. 특히, 이름에서 알 수 있듯이 NumPy 배열 (기능, 원시 이미지 등)의 입력 세트를 가져와 HDF5 형식으로 작성하는 역할을하는 HDF5DatasetWriter라는 Python 클래스를 정의해야합니다.
이 클래스 내에서 기능을 빌드하려면 두 개의 Python 패키지 만 필요합니다. 내장된 os 모듈과 h5py이므로 HDF5 바인딩에 액세스 할 수 있습니다.
거기에서 생성자를 정의하겠습니다.
# import the necessary packages
import h5py
import os
class HDF5DatasetWriter:
def __init__(self, dims, outputPath, dataKey="images", bufSize=1000):
# check to see if the output path exists, and if so, raise
# an exception
if os.path.exists(outputPath):
raise ValueError(
"The supplied `outputPath` already "
"exists and cannot be overwritten. Manually delete "
"the file before continuing.",
outputPath,
)
# open the HDF5 database for writing and create two datasets:
# one to store the images/features and another to store the
# class labels
self.db = h5py.File(outputPath, "w")
self.data = self.db.create_dataset(dataKey, dims, dtype="float")
self.labels = self.db.create_dataset("labels", (dims[0],), dtype="int")
# store the buffer size, then initialize the buffer itself
# along with the index into the datasets
self.bufSize = bufSize
self.buffer = {"data": [], "labels": []}
self.idx = 0
HDF5DatasetWriter의 생성자는 4개의 매개 변수를 허용하며 그 중 2개는 선택 사항입니다. dims
매개 변수는 데이터 세트에 저장할 데이터의 크기 또는 모양을 제어합니다. dims
를 NumPy
의 .shape
라고 생각할 수 있습니다. 28 × 28 = 784 MNIST 데이터 세트의 (플래 팅 된) 원시 픽셀 강도를 저장하는 경우 MNIST에 각각 784의 차원을 가진 70,000 개의 예제가 있으므로 dims = (70000, 784) 입니다. CIFAR-10
이미지의 경우 CIFAR-10 데이터 세트에 총 60,000 개의 이미지가 있으며 각 이미지는 32x32x3
RGB 이미지로 표시되므로 dims = (60000, 32, 32, 3)
입니다.
전이 학습 및 특징 추출의 맥락에서 VGG16 아키텍처
를 사용하고 최종 POOL
계층 이후에 출력을 가져옵니다. 최종 POOL 레이어의 출력은 512x 7 x 7
이며, 이 차원을 펼치면 길이가 25,088
인 특징 벡터를 생성합니다. 따라서 특징 추출에 VGG16을 사용하는 경우 dims = (N, 25088)
을 설정합니다. 여기서 N은 데이터 세트의 총 이미지 수입니다.
HDF5DatasetWriter 생성자의 다음 매개 변수는 outputPath
입니다. 이것은 출력 HDF5 파일이 디스크에 저장 될 경로입니다. 선택적 dataKey는 알고리즘이 학습 할 데이터를 저장할 데이터 세트의 이름입니다. 대부분의 경우 원시 이미지를 HDF5 형식으로 저장하므로이 값의 기본값은 "image"입니다. CNN에서 추출한 기능을 파일에 저장하고 있음을 나타 내기 위해 dataKey = "features"를 설정합니다.
마지막으로 bufSize
는 인 메모리 버퍼의 크기를 제어하며 기본적으로 1,000 개의 특징 벡터 / 이미지로 설정됩니다. bufSize에 도달하면 버퍼를 HDF5 데이터 세트로 넘깁니다.
그런 다음 outputPath
가 이미 존재하는지 확인합니다. 이 경우 기존 데이터베이스를 덮어 쓰지 않기 때문에 최종 사용자에게 오류가 발생합니다.
제공된 outputPath
를 사용하여 쓰기위한 HDF5 파일을 엽니다. dataKey 이름과 제공된 값을 사용하여 데이터 세트를 만듭니다. 여기에 원시 이미지 / 추출 된 기능이 저장됩니다. 두 번째 데이터 세트를 생성합니다. 이 데이터 세트는 데이터 세트의 각 레코드에 대한 (정수) 클래스 레이블을 저장한 다음 버퍼를 초기화합니다.
다음으로 버퍼에 데이터를 추가하는 데 사용되는 add
메서드입니다.
def add(self, rows, labels):
# add the rows and labels to the buffer
self.buffer["data"].extend(rows)
self.buffer["labels"].extend(labels)
# check to see if the buffer needs to be flushed to disk
if len(self.buffer["data"]) >= self.bufSize:
self.flush()
add 메서드에는 두 개의 매개 변수가 필요합니다. 데이터 세트에 추가 할 행
과 해당하는 클래스
라벨입니다. 행과 레이블은 모두 각 버퍼에 추가됩니다. 버퍼가 가득 차면 flush 메소드를 호출하여 파일을 작성하고 재설정합니다.
플러시 방법에 대해 이제 함수를 정의하겠습니다.
def flush(self):
# write the buffers to disk then reset the buffer
i = self.idx + len(self.buffer["data"])
self.data[self.idx : i] = self.buffer["data"]
self.labels[self.idx : i] = self.buffer["labels"]
self.idx = i
self.buffer = {"data": [], "labels": []}
또한 storeClassLabels라는 편리한 유틸리티 함수를 정의합니다.이 함수가 호출되면 별도의 데이터 세트에 클래스 레이블의 원래 문자열 이름을 저장합니다.
def storeClassLabels(self, classLabels):
# create a dataset to store the actual class label names,
# then store the class labels
dt = h5py.special_dtype(vlen=str) # `vlen=unicode` for Py2.7
labelSet = self.db.create_dataset("label_names", (len(classLabels),), dtype=dt)
labelSet[:] = classLabels
마지막으로 마지막 함수 close는 버퍼에 남아있는 데이터를 HDF5에 쓰고 데이터 세트를 닫는데 사용됩니다.
def close(self):
# check to see if there are any other entries in the buffer
# that need to be flushed to disk
if len(self.buffer["data"]) > 0:
self.flush()
# close the dataset
self.db.close()
HDF5DatasetWriter
는 머신 러닝이나 딥러닝과 전혀 관련이 없습니다. 단순히 데이터를 HDF5 형식으로 저장하는 데 사용되는 클래스일 뿐입니다. 딥러닝을 계속하면서 새로운 문제를 설정할 때 초기 작업의 대부분은 작업할 수 있는 형식으로 데이터를 가져 오는 것임을 알게 될 것입니다. 조작하기 쉬운 형식의 데이터가 있으면 머신러닝 및 딥러닝 기술을 데이터에 적용하기가 훨씬 쉬워집니다.
즉, HDF5DatasetWriter
클래스는 딥 러닝 및 컴퓨터 비전에 특화되지 않은 유틸리티 클래스입니다.
'keras > 2. Feature Extractors' 카테고리의 다른 글
4. Training a Classifier on Extracted Features (0) | 2020.08.28 |
---|---|
3. The Feature Extraction Process (0) | 2020.08.24 |
1. Networks as Feature Extractors (0) | 2020.08.22 |