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 매개 변수는 데이터 세트에 저장할 데이터의 크기 또는 모양을 제어합니다. dimsNumPy.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 클래스는 딥 러닝 및 컴퓨터 비전에 특화되지 않은 유틸리티 클래스입니다.


hdf5datasetwriter.py
0.00MB

 

+ Recent posts