2024. 1. 17. 21:32ㆍ딥러닝 모델: fastai
♣ 이미지네트
- 이미지넷
범주 1,000개, 픽셀 약 500개로 표현된 다양한 크기의 이미지를 130만 장 제공.
- MNIST
5만 장으로 구성된 28*28 픽셀의 흑백 숫자 손글씨 이미지
- CIFAR10
6만 장으로 구성된 32*32 픽셀 크기의 컬러 이미지. 전체 이미지는 10개의 범주로 구분됨.
이미지네트는 전체 이미지넷 데이터 중 매우 다른 범주를 10개만 선택하여 구성한 데이터셋임. 대용량 이미지넷과 달리 저렴하면서도 빠르게 분류 모델을 만들 수 있음.
이미지네트 데이터셋 다운로드하기
5장에서 다룬 '사전 크기 조절' 기법을 적용하여 데이터셋을 DataLoaders 객체로 만들기
- get_y = parent_label
각 이미지 파일의 상위 폴더 이름을 이미지의 레이블로 반환하는 함수
-item_tfms, batch_tfms
사전 크기 조절 작업.
item_tfms는 전체 너비나 높이를 기준으로 이미지를 자름. 모든 이미지를 같은 크기로 만듦
batch_tfms는 이미지를 자른 후 증강하는 단계를 의미함. 배치 단위의 데이터에 적용되어 빠르게 처리함.
구성한 dls 확인하기
학습 모델 만들어서 학습시키기
- n_out=dls.c
데이터의 클래스 수
*vision_learner VS Learner
위의 코드에서는 Learner를 이용해서 학습기를 만듦. 하지만 Chapter 5 에서는 vision_learner를 이용함.
vision_learner는 fastai 라이브러리에서 이미지 분류 작업에 특화된 학습기(Learner)를 생성하는 함수임.
vision_learner를 사용하면 이미지 분류 작업에 대한 기본 구성이 미리 되어 있어서 편리함. 이 함수는 데이터 로딩과 모델 생성에 필요한 많은 설정을 자동으로 처리해줌.
만약 learn = vision_learner(dls, xresnet50) 이런 식으로 구성하면 데이터셋 dls와 모델 xresnet50을 기반으로 한 이미지 분류 학습기가 생성됨. 내부적으로는 학습률 스케줄링, 가중치 초기화, 데이터 증강, 이미지 분류 작업에 필요한 설정이 자동으로 적용됨
이에 비해 Learner를 직접 생성하는 위의 코드에서는 사용자가 더 많은 설정을 직접 제어할 수 있음. 따라서 보다 세부적이거나 특수한 상황에 대응할 때 유용함.
♣ 정규화
데이터의 평균과 표준편차 구하기
데이터에서 배치 하나를 가져와서 채널 축을 제외한 모든 축값의 평균과 표준편차를 살펴본다.
- dim=[0, 2, 3]
정규화를 위해 평균과 표준 편차를 계산할 때, 주로 이미지 데이터의 각 채널에 대한 평균과 표준 편차를 계산함. 이미지 데이터는 보통 (배치 크기, 채널 수, 높이, 너비)의 형태를 가지며 dim 매개 변수는 어떤 차원을 축소할지 지정함.
dim=[0, 2, 3]은 각 배치에 대해 채널 축(1번 축)을 제외한 높이와 너비의 차원을 평균과 표준편차를 계산하는 데 사용함.
위의 반환값 중 첫 번째는 평균을, 두 번째는 표준 편차를 나타냄. 각 채널(색상 채널)에 대한 값이며 순서대로 빨강, 초록, 파랑 채널임.
데이터 정규화하기
데이터 증강을 미니배치 단위로 처리하므로 batch_tfms에 Normalize 변형을 추가하여 데이터를 정규화할 수 있음
imagenet_stats는 이미지넷 데이터셋에서 계산된 평균과 표준 편차의 튜플임. 이미지넷 데이터셋에서 계산된 평균과 표준 편차를 사용하는 것은 이미지 데이터를 정규화하는 흔한 방법 중 하나임. from_stats 메서드는 평균과 표준 편차를 사용하여 정규화 변환을 생성함. *연산자를 사용하면 튜플의 각 요소가 개별 인자로 전달됨.
정규화 후의 평균과 표준편차 확인하기
정규화가 모델 학습에 미치는 영향 알아보기
모델을 배포할 때는 학습에 사용한 정규화 관련 통계 정보를 함께 제공해야 함. 배포된 모델로 추론이나 전이학습을 수행하려면 같은 통계 정보를 사용해야 하기 때문. 즉, 현재의 데이터를 해당 모델의 정규화 자료를 이용하여 정규화한 뒤 모델을 사용해야 한다는 것.
♣ 점진적 크기 조절
학습할 때, epoch 대부분을 작은 이미지로 진행하면 학습에 걸리는 시간이 많이 단축되며 큰 이미지로 학습을 마무리하면 최종 정확도가 훨씬 높아짐. 이 접근법을 점진적 크기 조절이라고 함.
점진적 크기 조절은 데이터 증강 기법의 일종으로도 볼 수 있는데, 점진적 크기 조절로 학습해나가면 일반화가 더 잘 됨.
작은 크기의 이미지로 학습 실시하기
우선 작은 크기의 이미지에 대한 DataLoaders를 생성한 후 fit_one_cycle 메서드로 평소보다 적은 epoch 동안 학습 실시
get_dls(64, 224) => get_dls(128, 128)
배치 크기는 64에서 128로, 이미지 크기는 224에서 128로 변화함. 즉 한 개 배치에 들어가는 이미지 수는 많아지고 이미지의 크기는 작아짐.
큰 이미지로 바꾼 뒤 미세조정 수행하기
그리고 Learner 내부의 DataLoaders를 큰 이미지의 DataLoaders로 교체한 다음 미세 조정을 수행함.
fine_tune을 이용해서 미세조정을 수행함. 점진적 크기 조절을 하기 전보다 성능이 향상됨
<이전: bs는 64, 이미지 크기는 224이던 시절. 맨 첫 학습>
*fit_one_cycle vs fine_tune
- fit_one_cycle
목적: 일반적으로 초기 학습 단계에서 모델을 빠르게 학습시키기 위한 함수
사용 시점: 주로 초기 학습 단계에서 사용
동작 방식
- 학습률을 사이클 형태로 조절하여 모델의 빠른 수렴 도모
- 한 사이클 동안 학습률을 증가시키고 다시 감소시키는 방식으로 학습 진행
- 주어진 epoch 동안 모델을 학습시킴
- fine_tune
목적: 이미 사전 훈련된 모델을 가져와서 특정 작업에 맞게 미세 조정하는 데 사용됨
사용 시점: 주로 사전 훈련된 모델을 가져와서 특정 작업에 맞게 조정할 때 사용
동작 방식
- 사전 훈련된 모델을 불러옴
- 추가적인 epoch 동안 새로운 데이터셋에 대해 모델을 미세 조정함
- fine_tune 함수는 fastai 라이브러리의 기본 학습률 조정 전략을 따르며 미세 조정 단계에서는 낮은 학습률을 사용하여 미세 조정이 안정적으로 이뤄지도록 함.
*주의 사항
사전 학습된 모델이 전이 학습하려는 문제와 유사하고 이미지 크기도 비슷한 경우에는 전이 학습에서 점진적 크기 조절을 하면 성능을 해칠 수도 있음. 유사한만큼 학습될 내용이 적어서 가중치에 많은 변화를 기대하기 어렵기 때문임. 오히려 이미 잘 구성된 가중치를 망가뜨릴 수도 있음.
반면 데이터셋이 사전 학습된 데이터와는 다른 크기와 스타일의 이미지로 구성된다면 점진적 크기 조절 방식이 유용할 것
♣ 테스트 데이터에서의 데이터 증강(테스트 시 증강, Test Time Augmentation, TTA)
TTA는 추론 또는 검증할 때 데이터 증강을 적용하여 각 이미지의 다양한 버전을 생성하고, 각 이미지와 증강된 이미지에 대한 예측의 최댓값이나 평균을 구하는 기법을 의미함.
TTA에서 fastai는 기본적으로 증강되지 않은 중심부 잘라내기와 더불어 임의로 증강된 이미지 네 장을 사용함.
결과를 보면 TTA는 추가 학습 없이도 성능을 끌어올림. 하지만 추론에 더 오랜 시간을 소요함. TTA로 이미지 다섯 장의 평균을 구한다면 추론 시간이 다섯 배 정도 더 걸림.
- learn.tta()
모델이 예측한 결과를 여러 가지 변환 및 증강을 적용하여 앙상블 형태로 예측 수행.
preds는 TTA를 적용한 각각의 예측결과를 담은 리스트임. targs는 실제 타깃값(레이블)임.
♣ 믹스업
많은 데이터를 보유하지 않거나 보유 데이터가 사전 학습된 모델이 학습한 데이터와 유사하지 않을 때 정확도를 높여주는 데이터 증강 기법.
각 이미지에 대한 믹스업의 작동 순서
- 데이터셋에서 임의로 다른 이미지를 선택함
- 임의로 가중치 고름
- 기존 이미지와 선택한 이미지의 가중 평균 구함. 이를 독립변수로 사용함
- 기존 이미지와 선택한 이미지 레이블의 가중 평균을 구함. 이를 종속변수로 사용함.
- dataset[randint(0, len(dataset))]
기존 데이터셋은 image1, target1임. 위의 믹스업 1단계에서는 임의로 다른 이미지와 타깃값을 선택함(image2, target2)
0과 dataset 길이 사이에서 랜덤한 정수를 구하여 dataset 중 하나의 데이터를 뽑아냄.
- t
임의로 가중치 선정
-t*image1 + (1-t)*image2
기존의 이미지와 새로 뽑은 이미지를 합해서 오리지널이 아닌 새로운 이미지를 만듦. 각 이미지의 픽셀값을 가져와서 해당 이미지를 몇 퍼센트씩 섞을지 정하는 것. 예를 들어 t=0.2라면 image1의 픽셀값은 20%씩, image2의 픽셀값은 80%씩 가져와서 새로운 이미지를 만드는 것임.
-t*target1+(1-t)*target2
타깃값 역시 해당 비율만큼 가져와서 설정함.
타깃값 알아보기
믹스업이 작동하려면 타깃값은 원-핫 인코딩되어야 함.
예를 들어 '교회' 이미지를 30%, 주유소 이미지를 70% 합쳐서 믹스업한다고 할 때 모델은 30%가 교회, 70%가 주유소임을 예측해야 한다. 범주가 10개고 '교회'는 index 2, '주유소'는 index 7에 해당한다고 가정했을 때 원-핫 인코딩된 타깃값은 아래와 같이 나오게 됨
교회에 해당하는 타깃값: [0, 0, 1, 0, 0, 0, 0, 0, 0, 0]
주유소에 해당하는 타깃값: [0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
새로운 이미지의 타깃값 = 0.3* [0, 0, 1, 0, 0, 0, 0, 0, 0, 0] + 0.7* [0, 0, 0, 0, 0, 0, 0, 1, 0, 0]
= [0, 0, 0.3, 0, 0, 0, 0, 0.7, 0, 0]
믹스업을 포함하여 모델 학습하기
Learner에 콜백(callback)을 추가하면 fastai가 믹스업을 내부적으로 처리함. 콜백은 학습 루프 내의 사용자 정의 행동을 주입하는 수단으로, fastai 내부에서 사용함.
믹스업 데이터로 모델을 학습시키면 겹친 이미지 때문에 학습이 더 어려워지지만, 각 epoch마다 임의의 조합으로 구성된 이미지를 보여주므로 과적합 문제가 발생할 가능성은 낮아진다.
♣ 레이블 평활화
모델이 훈련 데이터의 라벨에 너무 확신을 가지지 않도록 하기 위한 기법 중 하나로, 모델이 훈련 데이터에 과적합되는 것을 방지하고 일반화 성능을 향상시키기 위해 사용함.
기본적으로 모든 클래스에 대한 라벨을 부드럽게 만들어줌. 일반적으로 정답 클래스에 대해 1.0보다 작은 양수값을 항당하고 다른 클래스에 대해서는 0 대신 작은 양수값을 할당함. 이렇게 함으로써 모델이 특정 클래스에 대해 너무 확신을 갖지 않도록 유도하며 모델이 더 많은 다양한 패턴을 학습하도록 도움.
레이블 평활화가 실제로 작동하는 방식
원-핫 인코딩된 레이블 중 0을 모두 e/N으로 바꿈. 여기서 N은 범주(클래스)의 개수이고 e는 파라미터(일반적으로 0.1)임
레이블의 합은 1이 되어야 하므로 인코딩된 레이블 중 1은 1-e+e/N으로 바꿈.
타깃값이 3일 때의 예시(N=10, e=0.1)
[0.01, 0.01, 0.01, 0.91, 0.01, 0.01, 0.01, 0.01, 0.01, 0.01]
실전에서는 레이블을 원-핫 인코딩하지 않는 편이 좋으며 그럴 필요도 없음.
레이블 평활화를 사용한 학습. 손실함수만 바꿔주면 됨.
♣ 실제 코드
https://www.kaggle.com/code/polljjaks/chapter-7/edit/run/159397209
'딥러닝 모델: fastai' 카테고리의 다른 글
Chapter8. 협업 필터링 깊게 알아보기 (0) | 2024.01.22 |
---|---|
Chapter 6. 그 밖의 영상 처리 문제 (0) | 2024.01.07 |
Chapter 5. 반려동물의 품종 분류하기 (0) | 2023.12.17 |
chapter4. 숫자 분류기 예시(숫자 3과 7의 손글씨 이미지 분류) (1) | 2023.12.08 |
이미지 분류 연습하기 (0) | 2023.12.04 |