반응형
블로그 이미지
개발자로서 현장에서 일하면서 새로 접하는 기술들이나 알게된 정보 등을 정리하기 위한 블로그입니다. 운 좋게 미국에서 큰 회사들의 프로젝트에서 컬설턴트로 일하고 있어서 새로운 기술들을 접할 기회가 많이 있습니다. 미국의 IT 프로젝트에서 사용되는 툴들에 대해 많은 분들과 정보를 공유하고 싶습니다.
솔웅

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함

카테고리


반응형

 

imgs = (batch[0][:10].permute(0, 2, 3, 1)) / 255
axes = d2l.show_images(imgs, 2, 5, scale=2)
for ax, label in zip(axes, batch[1][:10]):
    d2l.show_bboxes(ax, [label[0][1:5] * edge_size], colors=['w'])

https://d2l.ai/chapter_computer-vision/object-detection-dataset.html

 

14.6. The Object Detection Dataset — Dive into Deep Learning 1.0.3 documentation

 

d2l.ai

 

14.6. The Object Detection Dataset

There is no small dataset such as MNIST and Fashion-MNIST in the field of object detection. In order to quickly demonstrate object detection models, we collected and labeled a small dataset. First, we took photos of free bananas from our office and generated 1000 banana images with different rotations and sizes. Then we placed each banana image at a random position on some background image. In the end, we labeled bounding boxes for those bananas on the images.

 

객체 감지 분야에는 MNIST, Fashion-MNIST와 같은 작은 데이터셋이 없습니다. 객체 감지 모델을 신속하게 시연하기 위해 작은 데이터 세트를 수집하고 레이블을 지정했습니다. 먼저 사무실에서 무료로 제공되는 바나나 사진을 찍어 회전과 크기가 다른 1000개의 바나나 이미지를 생성했습니다. 그런 다음 일부 배경 이미지의 임의 위치에 각 바나나 이미지를 배치했습니다. 결국 이미지의 바나나에 대한 경계 상자에 레이블을 지정했습니다.

 

14.6.1. Downloading the Dataset

The banana detection dataset with all the image and csv label files can be downloaded directly from the Internet.

 

모든 이미지 및 csv 레이블 파일이 포함된 바나나 감지 데이터 세트는 인터넷에서 직접 다운로드할 수 있습니다.

 

%matplotlib inline
import os
import pandas as pd
import torch
import torchvision
from d2l import torch as d2l

#@save
d2l.DATA_HUB['banana-detection'] = (
    d2l.DATA_URL + 'banana-detection.zip',
    '5de26c8fce5ccdea9f91267273464dc968d20d72')

위 코드는 데이터셋을 다운로드하기 위한 설정과 관련된 내용을 포함하고 있습니다. 코드를 한 줄씩 살펴보겠습니다.

  • %matplotlib inline: 이는 Jupyter Notebook 환경에서 Matplotlib 그래프를 인라인으로 표시하도록 설정하는 명령입니다. Matplotlib 그래프가 노트북 내에서 바로 표시되도록 해줍니다.
  • import os: 파이썬 내장 라이브러리인 os 모듈을 불러옵니다. 파일 및 디렉토리 경로 관련 기능을 사용할 수 있도록 해줍니다.
  • import pandas as pd: 데이터 분석과 조작을 위한 판다스 라이브러리를 불러옵니다. 관례상 판다스는 pd로 축약하여 사용됩니다.
  • import torch: 파이토치 라이브러리를 불러옵니다. 딥러닝 모델을 구축하고 훈련하기 위한 도구를 제공합니다.
  • import torchvision: 파이토치에서 제공하는 컴퓨터 비전 관련 라이브러리입니다. 이미지 데이터셋 및 전처리 기능을 포함하고 있습니다.
  • from d2l import torch as d2l: "Dive into Deep Learning" 교재의 파이토치 관련 도우미 함수들을 가져옵니다. d2l은 이러한 도우미 함수들을 사용하기 위한 이름 공간입니다.
  • d2l.DATA_HUB['banana-detection']: 데이터셋을 다운로드하기 위한 정보를 딕셔너리로 정의합니다. 해당 정보에는 데이터셋의 다운로드 URL과 데이터셋의 해시값이 포함됩니다. 데이터셋의 해시값은 데이터의 무결성을 검증하기 위해 사용됩니다.
    • 'banana-detection.zip': 데이터셋의 압축 파일 이름입니다.
    • '5de26c8fce5ccdea9f91267273464dc968d20d72': 데이터셋 파일의 해시값입니다. 이 값은 데이터 파일의 무결성을 확인하기 위해 사용됩니다. 데이터가 변조되지 않았는지 확인하는 용도로 사용됩니다.
  •  

14.6.2. Reading the Dataset

We are going to read the banana detection dataset in the read_data_bananas function below. The dataset includes a csv file for object class labels and ground-truth bounding box coordinates at the upper-left and lower-right corners.

 

아래의 read_data_bananas 함수에서 바나나 감지 데이터 세트를 읽을 것입니다. 데이터 세트에는 개체 클래스 레이블에 대한 csv 파일과 왼쪽 상단 및 오른쪽 하단 모서리의 실측 경계 상자 좌표가 포함되어 있습니다.

 

#@save
def read_data_bananas(is_train=True):
    """Read the banana detection dataset images and labels."""
    data_dir = d2l.download_extract('banana-detection')
    csv_fname = os.path.join(data_dir, 'bananas_train' if is_train
                             else 'bananas_val', 'label.csv')
    csv_data = pd.read_csv(csv_fname)
    csv_data = csv_data.set_index('img_name')
    images, targets = [], []
    for img_name, target in csv_data.iterrows():
        images.append(torchvision.io.read_image(
            os.path.join(data_dir, 'bananas_train' if is_train else
                         'bananas_val', 'images', f'{img_name}')))
        # Here `target` contains (class, upper-left x, upper-left y,
        # lower-right x, lower-right y), where all the images have the same
        # banana class (index 0)
        targets.append(list(target))
    return images, torch.tensor(targets).unsqueeze(1) / 256

위 코드는 바나나 검출 데이터셋의 이미지와 레이블을 읽어오는 함수를 정의하고 있습니다. 코드를 한 줄씩 살펴보겠습니다.

  • def read_data_bananas(is_train=True):: 이 함수는 바나나 검출 데이터셋의 이미지와 레이블을 읽어오는 기능을 수행합니다. is_train 매개변수는 데이터셋이 훈련용인지 검증용인지를 나타내며, 기본값은 True입니다.
  • data_dir = d2l.download_extract('banana-detection'): 데이터셋을 다운로드하고 압축을 해제하여 저장할 디렉토리를 지정합니다. download_extract 함수를 사용하여 데이터셋을 다운로드하고 압축을 해제합니다.
  • csv_fname = os.path.join(data_dir, 'bananas_train' if is_train else 'bananas_val', 'label.csv'): 데이터셋의 레이블 정보가 담긴 CSV 파일의 경로를 지정합니다. is_train이 True인 경우 훈련용 데이터셋의 레이블 파일 경로를, 그렇지 않은 경우 검증용 데이터셋의 레이블 파일 경로를 지정합니다.
  • csv_data = pd.read_csv(csv_fname): Pandas를 사용하여 CSV 파일을 읽어 데이터를 데이터프레임 형태로 가져옵니다.
  • csv_data = csv_data.set_index('img_name'): 데이터프레임에서 'img_name' 열을 인덱스로 설정합니다. 각 이미지 파일의 이름을 인덱스로 사용하여 이미지와 레이블을 연결할 수 있도록 합니다.
  • images, targets = [], []: 이미지와 레이블을 저장하기 위한 빈 리스트를 생성합니다.
  • for img_name, target in csv_data.iterrows():: 데이터프레임을 순회하면서 이미지 이름과 레이블 정보를 하나씩 가져옵니다.
    • images.append(torchvision.io.read_image(...)): 이미지 파일을 읽어와서 리스트에 추가합니다. torchvision.io.read_image 함수를 사용하여 이미지 파일을 읽습니다.
    • targets.append(list(target)): 레이블 정보를 리스트에 추가합니다. 레이블은 클래스와 바운딩 박스의 좌표로 구성되어 있습니다.
  • return images, torch.tensor(targets).unsqueeze(1) / 256: 읽어온 이미지와 레이블을 반환합니다. 레이블을 텐서로 변환하고 바운딩 박스의 좌표 값을 [0, 1] 범위로 스케일링하여 반환합니다.

 

By using the read_data_bananas function to read images and labels, the following BananasDataset class will allow us to create a customized Dataset instance for loading the banana detection dataset.

 

read_data_bananas 함수를 사용하여 이미지와 레이블을 읽으면 다음 BananasDataset 클래스를 통해 바나나 감지 데이터 세트를 로드하기 위한 사용자 지정 Dataset 인스턴스를 만들 수 있습니다.

 

#@save
class BananasDataset(torch.utils.data.Dataset):
    """A customized dataset to load the banana detection dataset."""
    def __init__(self, is_train):
        self.features, self.labels = read_data_bananas(is_train)
        print('read ' + str(len(self.features)) + (f' training examples' if
              is_train else f' validation examples'))

    def __getitem__(self, idx):
        return (self.features[idx].float(), self.labels[idx])

    def __len__(self):
        return len(self.features)

위 코드는 PyTorch의 Dataset 클래스를 상속받아 바나나 검출 데이터셋을 사용하기 위한 사용자 정의 데이터셋 클래스를 정의하고 있습니다. 코드를 한 줄씩 살펴보겠습니다.

  • class BananasDataset(torch.utils.data.Dataset):: BananasDataset은 torch.utils.data.Dataset 클래스를 상속받아 사용자 정의 데이터셋 클래스를 정의하고 있습니다.
  • def __init__(self, is_train):: 클래스의 생성자 메서드입니다. 데이터셋의 초기화 작업을 수행합니다. is_train 매개변수는 데이터셋이 훈련용인지 검증용인지를 나타내며, 해당 데이터셋을 읽어와서 self.features와 self.labels에 저장합니다. 또한 읽어온 예제의 개수를 출력합니다.
  • def __getitem__(self, idx):: 데이터셋의 특정 인덱스 idx에 해당하는 샘플을 반환합니다. 해당 샘플의 이미지 데이터와 레이블을 튜플로 반환합니다. 이미지 데이터는 float 타입으로 변환되어 반환됩니다.
  • def __len__(self):: 데이터셋의 전체 샘플 개수를 반환합니다. 데이터셋의 길이를 알려주는 역할을 합니다.

이렇게 정의된 BananasDataset 클래스를 사용하면 데이터로더를 생성하여 모델 학습에 활용할 수 있습니다. 이 클래스는 데이터셋을 효율적으로 관리하고 모델 학습에 필요한 샘플과 레이블을 제공하는데 도움을 줍니다.

 

Finally, we define the load_data_bananas function to return two data iterator instances for both the training and test sets. For the test dataset, there is no need to read it in random order.

 

마지막으로 훈련 세트와 테스트 세트 모두에 대해 두 개의 데이터 반복자 인스턴스를 반환하도록 load_data_bananas 함수를 정의합니다. 테스트 데이터 세트의 경우 무작위 순서로 읽을 필요가 없습니다.

 

#@save
def load_data_bananas(batch_size):
    """Load the banana detection dataset."""
    train_iter = torch.utils.data.DataLoader(BananasDataset(is_train=True),
                                             batch_size, shuffle=True)
    val_iter = torch.utils.data.DataLoader(BananasDataset(is_train=False),
                                           batch_size)
    return train_iter, val_iter

위의 코드는 '바나나 감지 데이터셋'을 로드하는 함수인 load_data_bananas를 정의하는 코드입니다. 아래에 코드를 한국어로 설명해보겠습니다.

  • load_data_bananas(batch_size): 이 함수는 바나나 감지 데이터셋을 로드하는 역할을 합니다. batch_size라는 매개변수를 입력으로 받습니다.
  • """바나나 감지 데이터셋을 로드합니다.""": 이 줄은 함수의 설명을 나타내는 주석입니다. 함수가 어떤 역할을 하는지 간단하게 설명하고 있습니다.
  • train_iter = torch.utils.data.DataLoader(BananasDataset(is_train=True), batch_size, shuffle=True): train_iter라는 변수에는 훈련용 데이터를 로드하기 위한 DataLoader 객체가 저장됩니다. BananasDataset(is_train=True)는 훈련 데이터용 바나나 감지 데이터셋을 나타냅니다. batch_size는 한 번에 처리할 데이터의 개수를 나타내며, shuffle=True는 데이터를 섞어서 순서를 랜덤하게 만듭니다.
  • val_iter = torch.utils.data.DataLoader(BananasDataset(is_train=False), batch_size): val_iter라는 변수에는 검증용 데이터를 로드하기 위한 DataLoader 객체가 저장됩니다. BananasDataset(is_train=False)는 검증 데이터용 바나나 감지 데이터셋을 나타냅니다. batch_size는 한 번에 처리할 데이터의 개수를 나타냅니다.
  • return train_iter, val_iter: 이 함수는 train_iter와 val_iter 두 가지 값을 반환합니다. 이 두 변수는 각각 훈련용 데이터와 검증용 데이터를 로드하는 DataLoader 객체입니다.

이 함수는 주어진 batch_size에 따라 훈련용과 검증용 바나나 감지 데이터를 DataLoader를 통해 로드하고, 이를 반환하는 역할을 합니다.

 

 

Let’s read a minibatch and print the shapes of both images and labels in this minibatch. The shape of the image minibatch, (batch size, number of channels, height, width), looks familiar: it is the same as in our earlier image classification tasks. The shape of the label minibatch is (batch size, m, 5), where m is the largest possible number of bounding boxes that any image has in the dataset.

 

미니배치를 읽고 이 미니배치에서 이미지와 레이블의 모양을 모두 인쇄해 보겠습니다. 이미지 미니배치의 모양(배치 크기, 채널 수, 높이, 너비)은 친숙해 보입니다. 이전 이미지 분류 작업과 동일합니다. 레이블 미니배치의 모양은 (배치 크기, m, 5)입니다. 여기서 m은 이미지가 데이터세트에 포함할 수 있는 최대 경계 상자 수입니다.

 

Although computation in minibatches is more efficient, it requires that all the image examples contain the same number of bounding boxes to form a minibatch via concatenation. In general, images may have a varying number of bounding boxes; thus, images with fewer than m bounding boxes will be padded with illegal bounding boxes until m is reached. Then the label of each bounding box is represented by an array of length 5. The first element in the array is the class of the object in the bounding box, where -1 indicates an illegal bounding box for padding. The remaining four elements of the array are the (x, y)-coordinate values of the upper-left corner and the lower-right corner of the bounding box (the range is between 0 and 1). For the banana dataset, since there is only one bounding box on each image, we have m=1.

 

미니 배치의 계산이 더 효율적이지만 연결을 통해 미니 배치를 형성하려면 모든 이미지 예제에 동일한 수의 경계 상자가 포함되어야 합니다. 일반적으로 이미지에는 다양한 수의 경계 상자가 있을 수 있습니다. 따라서 m 미만의 경계 상자가 있는 이미지는 m에 도달할 때까지 잘못된 경계 상자로 채워집니다. 그런 다음 각 경계 상자의 레이블은 길이가 5인 배열로 표시됩니다. 배열의 첫 번째 요소는 경계 상자에 있는 개체의 클래스이며 여기서 -1은 패딩에 대한 잘못된 경계 상자를 나타냅니다. 배열의 나머지 4개 요소는 경계 상자의 왼쪽 위 모서리와 오른쪽 아래 모서리의 (x, y) 좌표 값입니다(범위는 0과 1 사이). 바나나 데이터셋의 경우 각 이미지에 경계 상자가 하나만 있으므로 m=1입니다.

 

batch_size, edge_size = 32, 256
train_iter, _ = load_data_bananas(batch_size)
batch = next(iter(train_iter))
batch[0].shape, batch[1].shape
  • batch_size, edge_size = 32, 256: 이 줄은 batch_size와 edge_size라는 두 개의 변수에 각각 32와 256 값을 할당합니다. batch_size는 한 번에 처리할 데이터의 개수이고, edge_size는 가로 또는 세로 방향의 이미지 크기를 나타냅니다.
  • train_iter, _ = load_data_bananas(batch_size): 이 줄은 load_data_bananas 함수를 이용하여 바나나 감지 훈련 데이터를 로드합니다. batch_size 매개변수를 통해 한 번에 처리할 데이터의 개수를 설정합니다. 반환되는 값 중에서 첫 번째 값인 train_iter는 훈련 데이터를 로드하는 DataLoader 객체를 나타냅니다. 두 번째 값인 _는 반환되는 두 번째 객체를 무시하는 역할을 합니다.
  • batch = next(iter(train_iter)): 이 줄은 훈련 데이터의 첫 번째 배치를 가져와서 batch 변수에 저장합니다. train_iter는 DataLoader 객체이므로, iter(train_iter)를 통해 이를 반복 가능한(iterable) 객체로 변환하고, next() 함수를 통해 첫 번째 배치를 가져옵니다.
  • batch[0].shape, batch[1].shape: 이 줄은 현재 로드된 배치의 첫 번째 요소와 두 번째 요소의 크기(shape)를 확인합니다. batch[0]은 이미지 데이터를 나타내며, batch[1]은 해당 이미지에 대한 레이블을 나타냅니다. .shape는 배열의 크기를 확인하는 메서드입니다.

이 코드는 주어진 batch_size와 edge_size를 사용하여 바나나 감지 훈련 데이터를 로드하고, 첫 번째 배치의 이미지 데이터와 레이블의 크기를 확인하는 역할을 합니다.

 

 

14.6.3. Demonstration

Let’s demonstrate ten images with their labeled ground-truth bounding boxes. We can see that the rotations, sizes, and positions of bananas vary across all these images. Of course, this is just a simple artificial dataset. In practice, real-world datasets are usually much more complicated.

 

레이블이 지정된 ground-truth 경계 상자가 있는 10개의 이미지를 시연해 보겠습니다. 바나나의 회전, 크기 및 위치가 이 모든 이미지에서 다르다는 것을 알 수 있습니다. 물론 이것은 단순한 인공 데이터 세트일 뿐입니다. 실제로 실제 데이터 세트는 일반적으로 훨씬 더 복잡합니다.

 

imgs = (batch[0][:10].permute(0, 2, 3, 1)) / 255
axes = d2l.show_images(imgs, 2, 5, scale=2)
for ax, label in zip(axes, batch[1][:10]):
    d2l.show_bboxes(ax, [label[0][1:5] * edge_size], colors=['w'])
  • imgs = (batch[0][:10].permute(0, 2, 3, 1)) / 255: 이 줄은 batch 변수에서 첫 번째 10개의 이미지 데이터를 선택하고, 차원 순서를 변경하며 픽셀 값 범위를 0에서 1 사이로 스케일링하여 imgs 변수에 저장합니다. 이미지의 픽셀 값은 원래 0에서 255 범위이지만, 여기서는 0에서 1 범위로 스케일을 조정합니다. permute(0, 2, 3, 1)는 차원을 순서대로 변경하는데, [0, 2, 3, 1] 순서로 변경함으로써 이미지의 차원 순서를 변경합니다.
  • axes = d2l.show_images(imgs, 2, 5, scale=2): imgs에 저장된 이미지 데이터를 2행 5열의 그리드 형태로 시각화하고, 각 이미지의 크기를 2배로 확대하여 axes 변수에 저장합니다. d2l.show_images 함수는 이미지들을 그리드로 나타내주는 도우미 함수입니다.
  • for ax, label in zip(axes, batch[1][:10]):: axes와 batch[1][:10]를 순회하면서 각 이미지와 해당 이미지의 레이블을 처리합니다.
  • d2l.show_bboxes(ax, [label[0][1:5] * edge_size], colors=['w']): d2l.show_bboxes 함수를 사용하여 이미지 위에 레이블에 해당하는 바운딩 박스를 그립니다. ax는 이미지를 나타내는 축(axes) 객체입니다. label[0][1:5] * edge_size는 레이블에서 바운딩 박스의 좌표를 추출하고 edge_size를 곱하여 실제 이미지 크기에 맞게 스케일링합니다. colors=['w']는 바운딩 박스의 색상을 흰색으로 설정합니다.

이 코드는 훈련 데이터의 첫 번째 10개 이미지를 시각화하고, 각 이미지에 해당하는 바운딩 박스를 그려서 바나나를 감지하는 레이블을 시각적으로 확인합니다.

 

14.6.4. Summary

  • The banana detection dataset we collected can be used to demonstrate object detection models.
  • 우리가 수집한 바나나 감지 데이터 세트는 객체 감지 모델을 시연하는 데 사용할 수 있습니다.

  • The data loading for object detection is similar to that for image classification. However, in object detection the labels also contain information of ground-truth bounding boxes, which is missing in image classification.
  • 객체 감지를 위한 데이터 로딩은 이미지 분류와 유사합니다. 그러나 객체 감지에서 레이블에는 이미지 분류에서 누락된 ground-truth 경계 상자의 정보도 포함됩니다.

 

14.6.5. Exercises

  1. Demonstrate other images with ground-truth bounding boxes in the banana detection dataset. How do they differ with respect to bounding boxes and objects?
  2. Say that we want to apply data augmentation, such as random cropping, to object detection. How can it be different from that in image classification? Hint: what if a cropped image only contains a small portion of an object?

 

 

 

반응형