2024.02.21
Inception Net 실습
(54일차 이론 이후 이어서 진행)
기본정보
데이터셋 : 캐글 견종 데이터셋 (https://www.kaggle.com/c/dog-breed-identification)
- train.zip, test.zip, submission, labels.csv 파일 다운로드
colab에서 zip 파일 풀기
# zip --> !unzip -qq 풀파일명 -d 풀어둘폴더경로
!unzip -qq "/content/train.zip" -d "/content/train/"
!unzip -qq "/content/test.zip" -d "/content/test/"
# 풀렸는지 확인
import os
import glob
len(list(glob.glob("/content/train/*.jpg"))) # 10222
len(list(glob.glob("/content/test/*.jpg"))) # 10357
추후 모델 활용시 편의성을 위해 train폴더의 정답을 폴더별로 구분
예) train/진돗개/ 111.jpg, 222.jpg 혹은 train/요크셔/ 333.jpg ... 등
# train/test org
train_data_folder= "/content/train/"
test_data_folder = "/content/test/"
# train--> 종류별로..
train_data_sub_folder= "/content/train_sub/"
test_data_sub_folder = "/content/test_sub/"
라벨인코딩 파일 확인
import pandas as pd
label_path ="/content/labels.csv"
label_text = pd.read_csv(label_path)
label_text.head()
# 학습할 데이터 견종의 수 확인
len(label_text.loc[:,"breed"].unique())
# = 120종
이미지 데이터 확인
import matplotlib.pyplot as plt
plt.figure(figsize=(12,12))
for c in range(9):
image_id = label_text.at[c, "id"]
image_breed = label_text.at[c, "breed"]
plt.subplot(3,3,c+1)
image_file = train_data_folder + image_id + ".jpg"
plt.imshow( plt.imread(image_file))
plt.title(str(c)+":"+image_breed)
plt.axis("off")
plt.show()
import matplotlib.pyplot as plt
import tensorflow as tf
from tensorflow.keras.utils import plot_model
import os
import shutil # colab 에서
import time
t1= time.time()
# 각 데이터의 breed 종류를 가져와서 폴더 없다면 폴더 생성, 있으면 이미지 복사 진행
for i in range(len(label_text)):
image_id = label_text.at[i, "id"]
iamge_breed = label_text.at[i,"breed"]
if os.path.exists( train_data_sub_folder+ iamge_breed)==False:
os.mkdir(train_data_sub_folder+ iamge_breed )
shutil.copy( train_data_folder +image_id+".jpg",
train_data_sub_folder + iamge_breed )
print('Done!!', time.time()-t1)
# 구글 드라이브에서 진행시 대략 40분 소요
모델 생성
from keras.applications.inception_v3 import InceptionV3
from keras.preprocessing import image
from keras.models import Model
from keras.layers import Dense, GlobalAveragePooling2D ,Dropout, MaxPooling2D
from keras.layers import Activation , Conv2D
from keras import backend as K
from keras.preprocessing.image import ImageDataGenerator
from keras.applications.inception_v3 import preprocess_input
from keras import optimizers
# imageNet 사전 학습 모델 불러오기
base_model = InceptionV3(weights='imagenet', include_top=False)
# 참고) 모델 구조 확인한다면
plot_model( base_model, show_shapes=True)
# train하는 과정에서 기존 모델의 구조 &가중치 값 모두 그대로 사용한다면
for layer in base_model.layers:
layer.trainable = False
# 분류는 우리 데이터에 맞게 진행해야하므로 뒷 부분 설계 진행
# 1) 최종 분류 종류 : 출력층의 노드 수
num_classes = len(os.listdir(train_data_sub_folder))
# 2) 기존 inception V3의 특징 추출하는 base_model에서 우리 데이터 종류 연ㄷ결
x = base_model.output
print(x)
print(x.shape)
# 3) 특징 추출 결과를 입력으로 120종 분류 모델 생성
# 20종 분류 위해 dense 레이어 추가
x = GlobalAveragePooling2D()(x)
x = Dropout(0.2)(x)
x = Dense(1024, activation="relu")(x)
x = Dropout(0.2)(x)
x = Dense(1024, activation="relu")(x)
x = Dropout(0.2)(x)
x = Dense(512, activation="relu")(x)
# 분류 모델 설정
preds = Dense(num_classes, activation="softmax")(x)
# model = Model(inputs = base_model.input, outputs = preds)
adam = optimizers.Adam(learning_rate=0.001,beta_1 = 0.9, beta_2 = 0.999 )
# 모델 compile
model.compile(optimizer = adam, loss = "categorical_crossentropy", metrics=["accuracy"])
# 이미지 정보 체크 위해 cv2로 진행
import cv2
train_datagen = ImageDataGenerator(
validation_split=0.1, # val 평가용
rescale = 1./255., # 정규화(필수)
rotation_range=40,
width_shift_range=0.2,
height_shift_range=0.2,
shear_range=0.2,
# zoom_range=0.2,
# horizontal_flip=True,
fill_mode='nearest'
)
valid_datagen=ImageDataGenerator(
validation_split=0.1,
rescale = 1./255., # 정규화(필수)
)
image_size = 299 # 원본 이미지 사이즈
batch_size = 16 # GPU에 따라서 유동적으로
# Generator 직접 해보기
train_generator = train_datagen.flow_from_directory(
# 1장을 뽑아낼 때에 대한 옵션
# 1) 어디서 뽑아낼지 폴더 경로
train_data_sub_folder,
# 2) 이 셋에 대한 용도를 지정
subset = "training",
# 3) 입력 모양 세팅 (선택)
target_size = ( image_size, image_size),
# 4) 기타 옵션
seed = 42, shuffle=True,
batch_size = batch_size,
class_mode = "categorical"
)
# val
valid_generator = valid_datagen.flow_from_directory(
# 1장을 뽑아낼 때에 대한 옵션....
# 1) 어디서 뽑아낼지 폴더 경로
train_data_sub_folder,
# 2) 이 셋에 대한 용도를 지정
subset = "validation",
# 3) 입력 모양 세팅 (선택)
target_size = ( image_size, image_size),
# 4) 기타 옵션
seed = 42, shuffle=False,
batch_size = batch_size,
class_mode = "categorical"
)
# checkpoint 추가
import os
cp_path = "training/cp-{epoch:04d}.ckpt"
cp_dir = os.path.dirname(cp_path)
cp_callback = tf.keras.callbacks.ModelCheckpoint(
cp_path,
verbose = 1,
save_weights_only = True
)
es_callback = tf.keras.callbacks.EarlyStopping(
monitor = "val_loss",
patience = 3
)
num_epochs = 50
my_steps_per_epoch = int(train_generator.n / batch_size)
history = model.fit_generator(
train_generator,
epochs = num_epochs,
validation_data = valid_generator,
steps_per_epoch = my_steps_per_epoch,
use_multiprocessing = True,
callbacks = [cp_callback, es_callback]
)
학습한 모델로 예측 진행
# 모델 예측
import os
import cv2
import pandas as pd
import numpy as np
test_set = []
test_set_ids = []
for curImage in os.listdir('/content/test'):
test_set_ids.append(os.path.splitext(curImage)[0])
curImage = cv2.imread('/content/test/'+curImage)
test_set.append(cv2.resize(curImage,(image_size, image_size)))
test_set = np.array(test_set, np.float32)/255.0
predictions= model.predict(test_set)
결과 제출 (캐글 이용시)
classes= {index:breed for breed,index in train_generator.class_indices.items()}
column_names = [classes[i] for i in range(120)]
predictions_df = pd.DataFrame(predictions)
predictions_df.columns = column_names
predictions_df.insert(0,'id', test_set_ids)
predictions_df.set_index('id',inplace=True)
predictions_df
predictions_df.to_csv('final_submission.csv',sep=",")
예측 결과 일부 이미지로 확인
test_img_list = list(glob.glob("/content/test/*.jpg"))
plt.figure(figsize=(12,12))
for c, test_img_path in enumerate(test_img_list[:9]):
plt.subplot(3,3,c+1)
plt.imshow(plt.imread(test_img_path))
curImg = cv2.imread( test_img_path)
curImg = cv2.resize(curImg, (image_size, image_size)) # 299,299
curImg = np.array([curImg/255.0])
curImg_pred = model.predict(curImg) # 120개의 확률값
pred_breed = column_names[np.argmax(curImg_pred)] # 확률값이 제일 높은 견종의 이름
plt.title(str(c)+":"+image_breed)
plt.axis("off")
plt.show()
'ASAC 빅데이터전문가과정 > DL' 카테고리의 다른 글
ASAC 59일차_딥러닝 12일차 (0) | 2024.09.05 |
---|---|
ASAC 57일차_딥러닝 11일차 (0) | 2024.09.05 |
ASAC 55일차_딥러닝 9일차 (0) | 2024.09.04 |
ASAC 54일차_딥러닝 8일차 (0) | 2024.09.04 |
ASAC 52일차_딥러닝 7일차 (0) | 2024.09.02 |