[Kaggle] Aerial Cactus Identification

eunsong·2023년 1월 5일
0

Kaggle

목록 보기
3/3
post-thumbnail

Aerial Cactus Identification

Determine whether an image contains a columnar cactus

[kaggle 링크]
https://www.kaggle.com/c/aerial-cactus-identification/overview

Data Description

This dataset contains a large number of 32 x 32 thumbnail images containing aerial photos of a columnar cactus (Neobuxbaumia tetetzo). Kaggle has resized the images from the original dataset to make them uniform in size. The file name of an image corresponds to its id.

You must create a classifier capable of predicting whether an images contains a cactus.

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

train, test data 가 압축되어 있으므로 압축을 풀어준다.

! unzip -q -o "/kaggle/input/aerial-cactus-identification/train.zip"
! unzip -q -o "/kaggle/input/aerial-cactus-identification/test.zip"

압축을 풀면 Output에 압축 풀어진 결과물이 나온다. Output에 train, test 폴더 생긴다.

우선 train data 를 살펴보기 위해 Input 에 위치한 train.csv를 돌려보았다.

train = pd.read_csv("/kaggle/input/aerial-cactus-identification/train.csv")
train

17500개의 train 데이터가 존재했고, 사진 안에 선인장이 있는지 없는지를 has_cactus 컬럼을 통해 확인 가능하다.
0, 1 두가지로 출력 class 를 2개로 잡으면 된다는 걸 알 수 있다.

train dataFrame에 이미지 경로를 넣어준다.
데이터 설명에 나와있듯이,
아까 압축풀었던 Output 의 train 안의 이미지들의 이름은 id에 해당하기 때문에 Output train 폴더 경로와 id 값을 합쳐 path를 만들어 준다.

train["path"] = "train/"+ train["id"]
train

임의의 train 이미지를 한번 살펴 본다.

from PIL import Image
Image.open("train/0004be2cfeaba1c0361d39e2b000257b.jpg")

Image.open("train/0004be2cfeaba1c0361d39e2b000257b.jpg").size

32x32 로 이루어진 아주 작은 사진이 있음을 알 수 있다.
선인장 썸네일이 너무 작아 어떤게 선인장인지 육안으로 구별하기 어려워보였다.

요번엔 케라스가 아닌, Pytorch로 구현해보기로 한다.

우선 위키 내용을 바탕으로 커스텀 데이터셋 클래스를 만들어 본다.

class CustomDataset(torch.utils.data.Dataset): 
  def __init__(self):
  데이터셋의 전처리를 해주는 부분

  def __len__(self):
  데이터셋의 길이., 총 샘플의 수를 적어주는 부분

  def __getitem__(self, idx): 
  데이터셋에서 특정 1개의 샘플을 가져오는 함수
  • len(dataset) 했을때 데이터셋의 크기 리턴.
  • dataset[i] 을 했을때 i번째 샘플 가져온다.

(출처: https://wikidocs.net/57165)

import torch
from torch.utils.data import DataLoader, Dataset
from torchvision import transforms as T

torch.utils.data.Dataset 를 상속 받기 위해 torch 와 dataset, 그리고 곧 뒤에 사용될 dataLoader도 임포트 해준다.

커스텀한 CatusDataSet Class이다.

class CactusDataSet(Dataset):
    # 생성자
    def __init__(self, df):
        self.df = df
        
    def __len__(self):
        return len(self.df)
    
    def __getitem__(self, idx):
    	# image 
        image_path = self.df["path"].iloc[idx] 
        image = Image.open(image_path)
        # 픽셀값의 범위를 0~1 범위로 Normalize 해줌
        image = T.Compose([T.Resize([150, 150]), T.ToTensor(), T.Normalize(mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225])])(image)
        # target 
        target = self.df["has_cactus"].iloc[idx]
        target = torch.tensor(target)
        
        return image, target

CuactusDataset 클래스는 torch의 torch.utils.data.Dataset를 상속 받았다.

잠시 파이썬 클래스 구현을 살펴보면
클래스는 아래와 같이 상속을 받는다.

class CactusDataSet(Dataset):

객체 생성 시 호출될 때 실행되는 초기화 함수, 생성자이다.

def __init__(self):

따라서 다시 본론으로 돌아와 CactusDataSet 클래스를 살펴보면

class CactusDataSet(Dataset):
    # 생성자
    def __init__(self, df):
        self.df = df
        
    def __len__(self):
        return len(self.df)

생성자로 받은 dataFrame 을 상속받은 Dataset의 dataframe 변수에 정의해주고, len(self.df) 로 상속받은 Dataset dataframe의 길이를 리턴한다.

def __getitem__(self, idx):
	# image 
    image_path = self.df["path"].iloc[idx] 
    image = Image.open(image_path)
    # 픽셀값의 범위를 0~1 범위로 Normalize 해줌
    image = T.Compose([T.Resize([150, 150]), T.ToTensor(), T.Normalize(mean = [0.485, 0.456, 0.406], std = [0.229, 0.224, 0.225])])(image)
    # target 
    target = self.df["has_cactus"].iloc[idx]
    target = torch.tensor(target)

	return image, target

정의된 dataframe의 path 컬럼의 값들 중 index 에 따라 가져옵니다.

image_path = self.df["path"].iloc[idx] 

iloc 을 이용하여 행 번호에 해당하는 path 값을 가져옵니다.

(참조 : pandas df 행/열 선택법 https://azanewta.tistory.com/34)

path로 이미지를 불러와 torchvision.transforms 로 데이터 전처리를 한다.

...

profile
study

0개의 댓글