[Kaggle] 침입종 모니터링

14996 단어 kagglekaggle

Invasive Species Monitoring

Identify images of invasive hydrangea

[kaggle 링크]
https://www.kaggle.com/c/invasive-species-monitoring


Data Description

The data set contains pictures taken in a Brazilian national forest. In some of the pictures there is Hydrangea, a beautiful invasive species original of Asia. Based on the training pictures and the labels provided, the participant should predict the presence of the invasive species in the testing set of pictures.

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))

input 폴더에 디렉토리 별로 어떤 파일이 있는지 확인한다.

train, test 폴더가 두개가 있다.
train - 훈련 세트
test - 알고리즘으로 레이블을 지정할 준비가 된 테스트 세트


!unzip -q -o ../input/invasive-species-monitoring/train_labels.csv.zip

train= pd.read_csv('./train_labels.csv')
train

train_labels.csv.zip 을 알집을 풀고 판다스로 csv 파일을 DataFrame으로 불러온다.

돌려본 결과다. 위 그림을 통해, invasive로 외래종 or 토종인지의 정답값을 Boolean 값으로 알 수 있다는 것을 알았다.

from PIL import Image
Image.open("/kaggle/input/invasivespecies/train/1.jpg")

name이 1번 그림을 열어보니, train 폴더의 1.jpg와 같다는걸 알았다.
train 데이타의 파일 경로 끝자리로 뽑아낸 걸 알 수 있었다.

# 주소 만들기
train['name'] = "/kaggle/input/invasivespecies/train/" + train["name"].astype(str) + ".jpg"
train

train name 컬럼에 train 폴더 주소값을 넣어준다. 그리고 확장자도 추가해준다.

from tensorflow.keras.preprocessing.image import ImageDataGenerator
idg = ImageDataGenerator()

train['invasive'] = train['invasive'].astype(str)

invasive 값들이 숫자이므로 스트링타입으로 바꿔준다.

from sklearn.model_selection import train_test_split  # 데이터를 나눈다


x_train, x_valid = train_test_split(train, test_size = 0.2, random_state = 1, stratify = train['invasive']) 

사이킷런의 model_selection 패키지 안의 train_test_split 모듈을 활용하여,
train set(학습데이터 셋)과 test set을 분리할 수 있다.


train / test 분리하는 목적?

정확히 말하면, train / test 가 아닌 train / validation 으로 볼 수 있다.

머신러닝 모델에서 train 데이터를 100% 학습시킨 후 test 데이터에 모델을 적용했을 때 성능이 생각보다 안나오는 경우가 많다. 이러한 현상을 overfitting 되었다고 한다.

이유는 모델이 내가 가진 학습 데이터에 너무 과적합되도록 학습한 나머지, 이를 조금이라도 벗어난 케이스에 대해서는 예측율이 현저하게 떨어지기 때문이다.

overfitting을 방지해주기 위해선 train 데이터 셋에서 train / validation 으로 일정 비율로 쪼갠 다음 학습 시에 train 셋으로 학습 후 중간중간 validation 셋으로 내가 학습한 모델 평가를 해주는 것이다.

만약, 모델이 과적합되었다면, validation 셋으로 검증시 예측율이나 오차율이 떨어지는 현상을 확인할 수 있으며, 이런 현상이 나타나면 학습을 종료한다.

딥러닝 모델도 마찬가지로 validation_data 를 지정해 줌으로써 매 epoch 마다 validation의 오차율을 확인하면서 과적합을 방지해야 좋은 성능의 모델을 만들 수 있다.

x_train, x_valid = train_test_split(train, test_size = 0.2, random_state = 1, stratify = train['invasive']) 

이 한줄의 코드로 train / validation 셋을 나눌 수 있다.

옵션 값

  • test_size : 테스트 셋 구성의 비율을 나타낸다. 0.2는 전체데이터의 20%를 test(validation) 셋으로 지정하겠다는 의미다. default값은 0.25이다.
  • shuffle : default값은 True 이다 split을 해주기 이전에 섞을건지 여부이다. 보통은 default 값으로 놔둔다.
  • statify : default값은 None 이다. classification을 다룰 때 매우 중요한 옵션값이다. stratify 값을 target으로 지정해주면 각각의 class 비율(ratio)을 train/validation에 유지해 준다. 한 쪽에 쏠려서 분배되는 것을 방지한다. 이 옵션을 지정해주지 않고 classification 문제를 다룬다면, 성능의 차이가 많이 날 수 있다. (...그래서 왜 train특정 컬럼값들을 넣는건데?..알아보자)
  • random_state : 세트를 섞을 때 해당 int 값을 보고 섞으며, 하이퍼 파라미터를 튜닝시 이 값을 고정해두고 튜닝해야 매번 데이터셋이 변경되는 것을 방지할 수 있다.
    (random_state 에 아무숫자 고정으로 넣어 똑같은 값이 나오도록 한다 -> 대조군을 명확히 설정하기 위해)
train_generator = idg.flow_from_dataframe(x_train, x_col='name', y_col='invasive', batch_size=64, target_size=(100,100))
valid_generator = idg.flow_from_dataframe(x_valid, x_col='name', y_col='invasive', batch_size=64, target_size=(100,100))

분리된 train / validation 학습 데이터 셋 각각 이미지 제너레이터 정의를 해준다.

flow_from_dataframe()

flow_from_dataframe 의 dataframe 은 판다스의 데이터프레임이다. 데이터 셋을 판다스의 데이터프레임에다가 저장 후 ImageDataGenerator 에 전달해준다는 의미며, 이미지 데이터가 있는 디렉토리 경로와 레이블값을 저장해준다.

https://techblog-history-younghunjo1.tistory.com/261

target_size 는 클수록 좋지만, 너무 커도 시간대비 효율이 안나기 때문에, (256,256) ~(300,300) 적당한 듯 하다.

  • 400 x 400 은 300 x 300 의 두배..
from tensorflow.keras import *
from tensorflow.keras.layers import *

from tensorflow.keras.applications.inception_v3 import InceptionV3
 
from tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint

model = Sequential()

iv = InceptionV3(include_top=False, pooling='avg')
es = EarlyStopping(patience=3, restore_best_weights= True)

mc = ModelCheckpoint("best.h5", save_best_only = True)

model.add(iv)
model.add(Dense(2, activation='softmax'))

model.compile(metrics='acc', loss='categorical_crossentropy', optimizer='adam')

model.fit(train_generator, validation_data = valid_generator, epochs = 100, callbacks = [es, mc]) 

model.load_weights("best.h5")

좋은 웹페이지 즐겨찾기