🟠. 폐암데이터 세트를 가지고 yolo v8 을 통해 암환자 찾기
◼ import
import os
import random
import shutil
import cv2
import glob
import yaml
import matplotlib.pyplot as plt
import ultralytics
from tqdm import tqdm
from PIL import Image
from ultralytics import YOLO
|
◼ 랜덤 시드 설정
random.seed(2024)
|
◼ 데이터 받아오기
! kaggle datasets download -d hamdallak/the-iqothnccd-lung-cancer-dataset
|
◼ 압축풀기
! unzip -q '/content/the-iqothnccd-lung-cancer-dataset.zip'
|
◼ data 폴더 만들어 주고 세개의 폴더 넣기
◼ 폴더 정리
# 폴더 경로 설정
data_root = '/content/The IQ-OTHNCCD lung cancer dataset'
file_root = f'{data_root}/data'
project_name = 'lung_cancer'
# 정리할 디렉토리 정의
train_file_root = f'{data_root}/{project_name}'
train_root = f'{data_root}/{project_name}/train'
valid_root = f'{data_root}/{project_name}/valid'
test_root = f'{data_root}/{project_name}/test'
|
◼ file_root 디렉토리 내의 모든 폴더 이름 확인
# 3종류의 클래스 디렉토리를 data 안으로 넣어줌
# file_root 에 있는 모든 디렉토리와 파일을 리스트로 만듦
cls_list = os.listdir(file_root)
cls_list
|
['Malignant cases', 'Bengin cases', 'Normal cases'] |
◼ [ train_root ], [ valid_root ], [ test_root] 라는 세 개의 폴더 생성
그 내부에 cls_list의 각 클래스 폴더를 생성
for folder in [train_root, valid_root, test_root]:
if not os.path.exists(folder):
os.makedirs(folder)
for cls in cls_list:
cls_folder = f'{folder}/{cls}'
if not os.path.exists(cls_folder):
os.makedirs(cls_folder)
|
|
◼ [ file_root ]내의 클래스별 서브디렉토리에서 파일을 랜덤하게 섞기
이를 학습(training), 검증(validation), 테스트(test) 세트로 나누는 작업
for cls in cls_list:
file_list = os.listdir(f'{file_root}/{cls}')
random.shuffle(file_list)
test_ratio = 0.1
num_file = len(file_list)
test_list = file_list[:int(num_file * test_ratio)]
valid_list = file_list[int(num_file * test_ratio):int(num_file * test_ratio)*2]
train_list = file_list[int(num_file * test_ratio)*2:]
print(test_list)
print(valid_list)
print(train_list)
for i in test_list:
shutil.copyfile(f'{file_root}/{cls}/{i}', f'{test_root}/{cls}/{i}')
for i in valid_list:
shutil.copyfile(f'{file_root}/{cls}/{i}', f'{valid_root}/{cls}/{i}')
for i in train_list:
shutil.copyfile(f'{file_root}/{cls}/{i}', f'{train_root}/{cls}/{i}')
|
|
◼ [ test_root ] 내의 모든 파일을 가져와서 랜덤하게 섞기
test_file_list = glob.glob(f'{test_root}/*/*')
random.shuffle(test_file_list)
test_file_list
|
◼ [ test_root ] 첫 10개의 이미지를 시각화
plt.figure(figsize=(20, 10))
for i in range(10):
test_img_path = os.path.join(test_root, test_file_list[i])
ori_img = Image.open(test_img_path).convert('RGB')
plt.subplot(2, 5, (i+1))
plt.title(test_file_list[i].split('/')[-2])
plt.imshow(ori_img)
plt.show()
|
◼ 데이터셋의 루트 디렉토리를 지정하기
project_root ='/content/The IQ-OTHNCCD lung cancer dataset/lung_cancer'
|
◼ [ project_root ] 내에 < data.yaml >이라는 YAML 파일을 생성하여, 데이터셋의 구조와 관련된 정보를 저장
data = dict()
data['train'] = train_root
data['val'] = valid_root
data['test'] = test_root
data['nc'] = len(cls_list)
data['names'] = cls_list
with open(f'{project_root}/data.yaml', 'w') as f:
yaml.dump(data, f)
|
◼ ultralytics 설치
! pip install ultralytics
|
◼ ultralytics 버전체크
import ultralytics
from ultralytics import YOLO
ultralytics.checks()
|
◼ 경로이동
%cd /content/The IQ-OTHNCCD lung cancer dataset/lung_cancer
|
/content/The IQ-OTHNCCD lung cancer dataset/lung_cancer |
◼ 모델 불러오기
model = YOLO('yolov8n-cls.pt')
|
◼ 학습하기
results = model.train(data=f'{data_root}/{project_name}', epochs=50, batch=8, device='cpu', name='lung_cancer_s')
|
|
◼ 결과 폴더 지정
result_folder = f'{project_root}/runs/classify/lung_cancer_s'
|
◼ YOLO 모델을 로드하고, best.pt라는 이름의 사전 훈련된 가중치 파일을 사용하여 해당 모델을 초기화
model = YOLO(f'{result_folder}/weights/best.pt')
model
|
◼ YOLO 모델의 val() 메서드를 사용하여 검증 또는 테스트 데이터셋에 대한 평가를 수행하고, 평가 지표를 반환
metrics = model.val(split='test')
metrics
|
◼ 모델의 성능 평가 지표인 top1과 top5 정확도를 출력
print('top1 accuracy: ', metrics.top1)
print('top5 accuracy: ', metrics.top5)
|
top1 accuracy: 0.9908257126808167 top5 accuracy: 1.0 |
|
◼ 추가 import
import numpy as np
import torch
from torchvision import transforms
|
◼ 이미지 데이터 전처리를 위한 변환(transform) 작업
IMG_SIZE = (512, 512)
test_data_transform = transforms.Compose([
transforms.Resize(IMG_SIZE),
transforms.ToTensor(),
])
|
◼ 이미지 파일을 열고, 지정된 전처리 변환을 적용한 후, PyTorch 텐서로 변환하여 모델 입력으로 준비하기
img = Image.open(test_file_list[0]).convert('RGB')
img_src = test_data_transform(img)
print(img_src.shape)
x_tensor = img_src.unsqueeze(0)
print(x_tensor.shape)
|
torch.Size([3, 512, 512]) torch.Size([1, 3, 512, 512]) |
|
◼ 모델에 이미지를 입력하여 예측 결과를 얻기
result = model(x_tensor)[0]
|
0: 512x512 Bengin cases 0.58, Normal cases 0.42, Malignant cases 0.00, 224.8ms Speed: 0.0ms preprocess, 224.8ms inference, 7.2ms postprocess per image at shape (1, 3, 512, 512) model(x_tensor): 모델을 호출하여 x_tensor 텐서에 대해 예측을 수행합니다. x_tensor는 모델의 입력으로 사용되는 이미지 텐서입니다. 모델의 forward 메서드가 호출되어 예측 결과를 반환합니다. |
◼ 모델의 예측 결과를 사용하여
입력 이미지의 실제 클래스(ground truth)와 모델이 예측한 클래스(및 그 확률)를 출력
gt = test_file_list[0].split('/')[-2]
pt = model.names[torch.argmax(result.probs.data).item()]
print(gt)
print(pt)
|
|
◼ 1개의 이미지 시각화 : 실제 클래스(ground truth)와 모델의 예측 클래스(predicted class)를 제목으로 표시
plt.figure(figsize=(3, 3))
plt.title(f'GT: {gt}, Predict: {pt}')
plt.imshow(np.array(img))
plt.show()
|
◼ 5개의 이미지 예측결과
plt.figure(figsize=(20,5))
for idx in range(5):
img = Image.open(test_file_list[idx]).convert('RGB')
img_src = test_data_transform(img)
x_tensor = img_src.unsqueeze(0)
result = model.predict(x_tensor)[0]
gt = test_file_list[0].split('/')[-2]
pt = model.names[torch.argmax(result.probs.data).item()]
plt.subplot(1, 5, (idx+1))
plt.title(f'GT:{gt}, Predict:{pt}')
plt.imshow(img)
plt.show()
|
@. 과제 : 안전장비 착용 감지 확인하기
데이터셋 : https://www.kaggle.com/datasets/andrewmvd/hard-hat-detection/data
'AI > 컴퓨터 비전' 카테고리의 다른 글
17. YOLO v8을 이용한 이상행동 탐지 (0) | 2024.08.12 |
---|---|
16. YOLO v8를 활용한 안전모 탐지 (0) | 2024.08.08 |
14. YOLO | 객체탐지 (0) | 2024.08.06 |
@. 과제 (0) | 2024.08.05 |
13. Faster R-CNN | 객체 탐지 (0) | 2024.07.25 |