[에이블 스쿨] 4차 미니프로젝트 | 이미지데이터모델링-얼굴인식(Face Recognition)

2024. 11. 25. 17:43·대외활동/에이블스쿨

이번 시각지능 딥러닝 프로젝트는 5일간 진행되었습니다.

 

프로젝트개요

주제 이미지 데이터 모델링 얼굴 인식 (Face Recognition)
데이터 다른 사람 얼굴 데이터, 개인 얼굴 데이터
데이터 출처 Kaggle, Roboflow Universe
  1. 데이터에 대한 적절한 전처리 및  keras를 이용한 학습 및 추론
2. 데이터에 대한 적절한 전처리 및 YOLO를 이용한 학습 및 추론

 

데이터 셋

keras 데이터

다른 사람 얼굴 이미지 데이터 LFW dataset  5750개의 폴더, 13223개의 이미지
개인 얼굴 이미지 데이터  내가 수집하기  최소 2500장

YOLO 데이터

다른 사람 얼굴 이미지 데이터 Face Recognition1 5979개의 이미지, 5979의 텍스트
  Face Recognition 2 4983개의 이미지, 4983개의 텍스트
개인 얼굴 이미지 데이터  내가 수집하기 최소 2500장

 

 

[1일차] FaceNet 모델 

1일차에는 개인 얼굴 이미지 데이터 셋을 수집하고 , FaceNet 모델을 생성했다.

데이터 수집

OpenCV 를 사용해 내 얼굴 이미지를 수집했다.

좋은 모델을 위해 다양한 각도와 표정으로 찍었다.

 

데이터 전처리

데이터 셋 분할

tf.keras.preprocessing.image_dataset_from_directory  |  TensorFlow v2.16.1

 

tf.keras.preprocessing.image_dataset_from_directory  |  TensorFlow v2.16.1

Generates a tf.data.Dataset from image files in a directory.

www.tensorflow.org

 

keras의 image_dataset_from_directory 을 사용하기 위해선 데이터 구조를 다음과 같이 해야한다.

 

main_directory/
...class_a/
......a_image_1.jpg
......a_image_2.jpg
...class_b/
......b_image_1.jpg
......b_image_2.jpg

 

class_a와 class_b 하위 디렉토리에서 이미지를 배치 단위로 가져오고, 함께 0과 1의 라벨도 제공한다.

여기서 0은 class_a에, 1은 class_b에 해당

위와 같이 0.2 비율로 데이터 분할을 했다. 

 

image_dataset_from_directory  함수 사용

## Training set 데이터 폴더를 데이터셋화
## 이 과정에서 Validation set도 생성
tr_idfd, val_idfd = image_dataset_from_directory(tr_data,                    ## Training 폴더 경로
                                                 class_names=['other','my'], ## 클래스 순서 지정
                                                 batch_size=32,              ## 이미지 덩어리 단위
                                                 image_size=(160,160),       ## 이미지 리사이즈
                                                 shuffle=True,               ## 섞어야 올바르게 분할됨
                                                 seed=2024,                  ## 재현성
                                                 validation_split=0.3,       ## 데이터 스플릿 비율
                                                 subset='both',              ## 데이터셋 나눔 방식
                                                 )

1. other 클래스는 라벨 0, my 클래스는 라벨 1로 매핑

2. 데이터를 한 번에 처리하는 배치 크기를 지정 (한 번에 32개의 이미지를 로드)

3. 모델의 입력 크기에 맞추기 위해 160x160 크기로 리사이즈

4. 데이터셋을 섞지 않으면 클래스별로 정렬된 상태로 불러올 가능성이 있으므로, Training-Validation 분할이 올바르게 되지 않을 수 있다. ->shuffle

5.이미지의 70%를 훈련에 사용하고 30%를 유효성 검사에 사용

 

스케일링

def rescale(image, label) :
    image = image / 255
    return image, label
    
tr_idfd_rescale = tr_idfd.map(rescale)
val_idfd_rescale = val_idfd.map(rescale)
te_idfd_rescale = te_idfd.map(rescale)

 

픽셀 값을 0~1 범위로 정규화

입력 이미지는 일반적으로 0~255 범위의 정수값을 가지는데, 이를 255로 나눠서 부동소수점 값으로 변환한다.

 

FaceNet 모델 

 

[1503.03832] FaceNet: A Unified Embedding for Face Recognition and Clustering

 

FaceNet: A Unified Embedding for Face Recognition and Clustering

Despite significant recent advances in the field of face recognition, implementing face verification and recognition efficiently at scale presents serious challenges to current approaches. In this paper we present a system, called FaceNet, that directly le

arxiv.org

 

 

 


[2일차] YOLO-cls 모델 

2일차에는 YOLO-cls를 사용했다.

데이터수집

1일차에 수집한 데이터를 그대로 사용했다.

데이터 전처리

데이터 셋 분할

이미지 분류 데이터 세트 개요 - Ultralytics YOLO 문서

 

이미지 분류 데이터 세트 개요

YOLO 분류 작업을 위한 데이터 세트 구조에 대해 알아보세요. 효과적인 교육을 위한 자세한 폴더 구조와 사용 예제입니다.

docs.ultralytics.com

 

YOLO-cls  을 사용하기 위해선 데이터 구조를 다음과 같이 해야한다.

cifar-10-/
|
|-- train/
|   |-- airplane/
|   |   |-- 10008_airplane.png
|   |   |-- 10009_airplane.png
|   |   |-- ...
|   |
|   |-- automobile/
|   |   |-- 1000_automobile.png
|   |   |-- 1001_automobile.png
|   |   |-- ...
|   |
|
|-- test/
|   |-- airplane/
|   |   |-- 10_airplane.png
|   |   |-- 11_airplane.png
|   |   |-- ...
|   |
|   |-- automobile/
|   |   |-- 100_automobile.png
|   |   |-- 101_automobile.png
|   |   |-- ...
|   |
|
|-- val/ (optional)
|   |-- airplane/
|   |   |-- 105_airplane.png
|   |   |-- 106_airplane.png
|   |   |-- ...
|   |
|   |-- automobile/
|   |   |-- 102_automobile.png
|   |   |-- 103_automobile.png
|   |   |-- ...
|   |

 

# 각 세트의 데이터 비율 설정
train_ratio = 0.7
val_ratio = 0.2
test_ratio = 0.1  # 선택 사항

YOLO-cls 모델 

분류 - Ultralytics YOLO 문서

from ultralytics import YOLO

# Load a model
model = YOLO("yolo11n-cls.pt")  # load a pretrained model (recommended for training)

n이 가장 빠르다 해서 yolo11n 을 사용했다.

 


 

[3일차] Annotation

3일차엔 데이터 수집 및 정제,Annotation 작업을 했다. 

- 온라인에서작업: Roboflow, CVAT 등

- 로컬에서작업: Ybat-master 등

 

 나는 roboflow를 활용하여 annotation과 augmentation을 진행했다.

Roboflow: Computer vision tools for developers and enterprises

 

Roboflow: Computer vision tools for developers and enterprises

Everything you need to build and deploy computer vision models, from automated annotation tools to high-performance deployment solutions.

roboflow.com

 

roboflow에선 객체에 bounding box를 그려 직접 labeling 까지 할 수 있다. 

Train, Valid, Test 비율을 설정 해주고 나눈 후 내가 원하는 방식으로 이미지 증강도 된다.

 


[4일차] YOLO 모델

 

3일차에 정제한 데이터를 사용해 yolo 모델 학습을 진행했다.

yolo 와 yolo-cls 의 차이는 다음과 같다.

  YOLO YOLO-cls
목적 객체 탐지 (위치 + 클래스 예측) 이미지 분류 (클래스만 예측)
입력 이미지 이미지
출력 Bounding Box + 클래스 클래스
적용 범위 다중 객체 탐지, 복잡한 이미지 단일 객체 분류, 단순 이미지
속도 및 경량성 탐지 연산으로 다소 무거움 경량화되어 더 빠름

 

데이터 전처리

Label 파일의 클래스 값 변경

Face Recognition1, Face Recognition2 데이터 라벨 정제 

  • 여러 클래스로 구분되어 있는 것을 하나로 통일
  • 이것은 다른 사람의 얼굴에 대해 전처리하는 작업
## txt 전체 파일을 리스트화
txt_list = sorted(glob.glob( os.path.join('/content/temp_dataset/labels', '*.txt')) )


for txt_file in txt_list :
    with open(txt_file, 'r') as f :
        lines = f.readlines()

    new_lines = []

    for line in lines :
        parts = line.strip().split()

        if not int(parts[0]) == 0 :
            new_line = f'{0} ' + ' '.join( parts[1:] )
            # new_line = f'{1} ' + ' '.join( parts[1:] ) ## 클래스 1로 변경 테스트
            new_lines.append( new_line )
            print('클래스 1으로 변경 : ', new_line)
        else :
            new_line = ' '.join( parts[0:] )
            new_lines.append( new_line )
            print('클래스 그대로 유지 : ', new_line)

    with open(txt_file, 'w') as f :
        f.write('\n'.join(new_lines) + '\n')

    print(f'파일 {txt_file} 처리 완료')

 

데이터 셋 분할

## 원본 폴더 경로들
source_folders = {'images': '/content/temp_dataset/images',
                  'labels': '/content/temp_dataset/labels'
                  }

## 타겟 폴더 경로들
target_folders = {'images':{'train':'/content/Datasets/images/train',
                            'val':'/content/Datasets/images/val',
                            # 'test':'/content/Datasets/images/test',
                            },
                  'labels':{'train':'/content/Datasets/labels/train',
                            'val':'/content/Datasets/labels/val',
                            # 'test':'/content/Datasets/labels/test',
                            }
                  }

 

  • 폴더 생성: /content/Datasets 아래에 필요한 폴더 구조를 생성.

 

## 데이터 스플릿 비율
split_size = 0.8

## images, labels 파일을 정렬하여 리스트화
image_list = sorted(glob.glob(os.path.join(source_folders['images'], '*')))
label_list = sorted(glob.glob(os.path.join(source_folders['labels'], '*')))

## 묶고 섞고 다시 리스트화
combined = list(zip(image_list, label_list))
random.shuffle(combined)
image_list, label_list = zip(*combined)

## 총 파일 수 계산
total_files = len(image_list)
tr_val_split = int(total_files * split_size)

print('전체 파일 수 : ', total_files)
print('training set 파일 수 : ', tr_val_split)
print('validation set 파일 수 : ', total_files - tr_val_split)

## train / val로 분리
tr_images, tr_labels = image_list[ : tr_val_split], label_list[ : tr_val_split]
val_images, val_labels = image_list[tr_val_split : ], label_list[tr_val_split : ]

print( 'training set 이미지 수 : ', len(tr_images), ' training set 라벨 수 : ', len(tr_labels) )
print( 'validation set 이미지 수 : ', len(val_images), 'validation set 라벨 수 : ', len(val_labels) )
  • 데이터 분리: 랜덤하게 데이터를 Training(80%)과 Validation(20%)으로 나눔.

Yolo 모델 

model = YOLO('yolo11n.pt')

 

어제 학습했던 모델보다 더 성능이 떨어지는 것을 알 수 있다. 

과도한 augmentation이 학습에 악영향을 미치는 것 같아 이미지 증강을 적절히 하는 것이 중요하다. 


[5일차] 로컬Cam에서의 실성능확인

Keras로 학습한 모델/ YOLO-cls로 학습한 모델/ YOLO로 학습한 모델

세가지의 모델을 개선하여 로컬Cam에서 실성능을 확인했다.

 

 

 


느낀 점

정확도가 떨어져 아쉬움이 많이 남는 프로젝트였다. 제한된 시간안에서 팀원들과 효율적으로 프로젝트를 진행하는 것이 중요하다는 것을 알게되었다. 세 모델을 전부다 손보기 어려웠고, 각 모델마다 접근 방법이 달랐기 때문에 역할을 나누어 튜닝했으면 더 좋은 성능의 모델을 뽑아낼 수 있었을 것 같다.

결국 모델링이란 데이터가 좋아야 좋은 모델이 나온다는 것을 알게 되었다. 따라서 데이터의 질을 높이는 것에 시간을 많이 투자해야하고, 이미지 증강을 신중히 해야한다.

다음 프로젝트엔 프로젝트의 큰 흐름을 파악하고 역할분담을 더 신중히 할 것이다. 또한 더 좋은 데이터를 얻기 위해 노력할 것이다. 

 

'대외활동 > 에이블스쿨' 카테고리의 다른 글

[에이블 스쿨] 2차 코딩마스터스 | 1일 1코딩 리뷰 이벤트  (2) 2024.11.28
[에이블 스쿨] 5차 미니프로젝트 | ASSO 대비  (1) 2024.11.26
[에이블 스쿨] 3차 미니프로젝트 | DL 모델링  (3) 2024.11.07
[에이블 스쿨] KES 2024, 한국 전자전 후기 | 스터디 활동  (2) 2024.10.29
[에이블 스쿨] 1차 코딩마스터스 | 기록 방법, 꿀팁  (2) 2024.10.11
'대외활동/에이블스쿨' 카테고리의 다른 글
  • [에이블 스쿨] 2차 코딩마스터스 | 1일 1코딩 리뷰 이벤트
  • [에이블 스쿨] 5차 미니프로젝트 | ASSO 대비
  • [에이블 스쿨] 3차 미니프로젝트 | DL 모델링
  • [에이블 스쿨] KES 2024, 한국 전자전 후기 | 스터디 활동
#코딩 공부
#코딩 공부
tildacoding 코딩 공부
  • #코딩 공부
    tildacoding
    #코딩 공부
  • 전체
    오늘
    어제
  • 글쓰기 관리자
  • Personal

    • 홈
    • 태그
    • 방명록
  • link

    • GITHUB
    • 분류 전체보기 (51)
      • Dev (12)
        • python (0)
        • 웹크롤링 (2)
        • 머신러닝 (3)
        • 딥러닝 (4)
        • 언어지능 딥러닝 (2)
        • SQL (1)
        • Spring (0)
      • 코딩테스트 (16)
        • 백준 (3)
        • 프로그래머스 (7)
        • 기타 문제 (2)
        • 코딩테스트를 위한 정리 (4)
      • Study (4)
        • 알고리즘 (2)
        • 자료구조 (2)
      • 대외활동 (18)
        • 에이블스쿨 (18)
        • 공모전 (0)
  • 공지사항

    • 루틴 skrrrrr
  • 인기 글

  • 태그

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.0
#코딩 공부
[에이블 스쿨] 4차 미니프로젝트 | 이미지데이터모델링-얼굴인식(Face Recognition)
상단으로

티스토리툴바