오전: 고양이, 개 분류하기
오후: 객체 탐지 기초
압축 풀고 train, test loader 설정
import zipfile
import os
from sklearn.model_selection import train_test_split
zip_file_path = '/content/drive/MyDrive/cat_dog.zip'
# 압축 해제할 폴더 경로
extracted_folder_path = '/content/drive/MyDrive/cat_dog_extracted'
# 압축 해제
with zipfile.ZipFile(zip_file_path, 'r') as zip_ref:
zip_ref.extractall(extracted_folder_path)
from tensorflow.keras.preprocessing.image import ImageDataGenerator
# 이미지 데이터 생성기 설정
datagen = ImageDataGenerator(rescale=1./255, validation_split=0.2)
# 훈련 데이터셋 생성
train_generator = datagen.flow_from_directory(
'/content/drive/MyDrive/cat_dog_extracted/PetImages',
target_size=(224, 224), # 이미지 크기 조절
batch_size=32,
class_mode='binary', # 이진 분류인 경우 'binary'
subset='training' # 훈련 데이터 설정
)
# 테스트 데이터셋 생성
test_generator = datagen.flow_from_directory(
'/content/drive/MyDrive/cat_dog_extracted/PetImages',
target_size=(224, 224),
batch_size=32,
class_mode='binary',
subset='validation' # 검증 데이터 설정
)
Found 20032 images belonging to 2 classes.
Found 5007 images belonging to 2 classes.
데이터셋 확인
import matplotlib.pyplot as plt
images, labels = next(train_generator)
# 가져온 배치의 첫 번째 이미지와 라벨 시각화
plt.figure(figsize=(10, 10))
for i in range(min(9, len(images))): # 처음 9장의 이미지만 표시
plt.subplot(3, 3, i+1)
plt.imshow(images[i])
plt.title(f"Label: {int(labels[i])}")
plt.axis("off")
plt.show()
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense
# Sequential 모델 생성
model = Sequential()
model.add(Conv2D(32, (3, 3), input_shape=(224, 224, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(64, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Conv2D(128, (3, 3), activation='relu'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(1, activation='sigmoid')) # 2 클래스 이진 분류
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
history_cnn = model.fit(train_generator, epochs=5, validation_data=test_generator)
cnn 정확도: 0.97%
from tensorflow.keras.applications import VGG16
# VGG16 모델 가져오기 (include_top=False로 설정하여 fully connected layers를 포함하지 않도록 설정)
base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
model = Sequential()
model.add(base_model)
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(1, activation='sigmoid')) # 2 클래스(고양이, 개) 이진 분류의 경우
# 기존 모델의 가중치를 동결하여 훈련하지 않도록 설정
for layer in base_model.layers:
layer.trainable = False
# 모델 컴파일
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# 모델 훈련
history_vgg = model.fit(train_generator, epochs=5, validation_data=test_generator)
vgg16 정확도: 98.30%
from tensorflow.keras.applications import ResNet50
# RESNET50 모델 가져오기 (include_top=False로 설정하여 fully connected layers를 포함하지 않도록 설정)
base_model = ResNet50(weights='imagenet', include_top=False, input_shape=(224, 224, 3))
model3 = Sequential()
model3.add(base_model)
model3.add(Flatten())
model3.add(Dense(256, activation='relu'))
model3.add(Dense(1, activation='sigmoid')) # 2 클래스(고양이, 개) 이진 분류의 경우
# 기존 모델의 가중치를 동결하여 훈련하지 않도록 설정
for layer in base_model.layers:
layer.trainable = False
# 모델 컴파일
model3.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# 모델 훈련
history_res = model3.fit(train_generator, epochs=15, validation_data=test_generator)
resnet50 정확도: 77.30%
다른 팀원들의 코드를 봤을때 차이가 전혀 없었음에도 RESNET의 정확도가 매우 높게 나왔다.
왜그런지 계속 파라미터를 바꿔보다가 IMAGE_SIZE를 (224, 224)에서 (150, 150)으로 변경하였더니 정확도가 올라갔다.
모든 경우에서 적용되진 않겠지만 여러가지 실험을 해봐야겠다.
!git clone https://github.com/Pseudo-Lab/Tutorial-Book-Utils
!mkdir -p ~/.kaggle
!cp kaggle.json ~/.kaggle
!chmod 600 ~/.kaggle/kaggle.json
!kaggle datasets download -d andrewmvd/face-mask-detection
!unzip -q /content/face-mask-detection.zip
import os
import glob
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import matplotlib.patches as patches
from bs4 import BeautifulSoup
img_path = '/content/images'
label_path = '/content/annotations'
img_list = sorted(glob.glob(img_path+'/*'))
annot_list = sorted(glob.glob(label_path+'/*'))
print(len(img_list))
print(len(annot_list))
853
853
## 바운딩 박스 시각화 함수 정의
def generate_box(obj):
xmin = float(obj.find('xmin').text)
ymin = float(obj.find('ymin').text)
xmax = float(obj.find('xmax').text)
ymax = float(obj.find('ymax').text)
return [xmin, ymin, xmax, ymax]
def generate_label(obj):
if obj.find('name').text == "with_mask":
return 1
elif obj.find('name').text == "mask_weared_incorrect":
return 2
return 0
def generate_target(file):
with open(file) as f:
data = f.read()
soup = BeautifulSoup(data, "html.parser")
objects = soup.find_all("object")
num_objs = len(objects)
boxes = []
labels = []
for i in objects:
boxes.append(generate_box(i))
labels.append(generate_label(i))
target = {}
target["boxes"] = boxes
target["labels"] = labels
return target
def plot_image(img_path, annotation):
img = mpimg.imread(img_path)
fig,ax = plt.subplots(1)
ax.imshow(img)
for idx in range(len(annotation["boxes"])):
xmin, ymin, xmax, ymax = annotation["boxes"][idx]
if annotation['labels'][idx] == 0 :
rect = patches.Rectangle((xmin,ymin),(xmax-xmin),(ymax-ymin),linewidth=1,edgecolor='r',facecolor='none')
elif annotation['labels'][idx] == 1 :
rect = patches.Rectangle((xmin,ymin),(xmax-xmin),(ymax-ymin),linewidth=1,edgecolor='g',facecolor='none')
else :
rect = patches.Rectangle((xmin,ymin),(xmax-xmin),(ymax-ymin),linewidth=1,edgecolor='orange',facecolor='none')
ax.add_patch(rect)
plt.show()
img_list.index(img_path+'/maksssksksss307.png')
bbox = generate_target(annot_list[232])
plot_image(img_list[232], bbox)