[AI/Hands-on ML] - [핸즈온 머신러닝] 14장(3) -케라스를 통한 CNN 구현 및 모델 사용
14. 8 분류와 위치 추정
사진에서 물체의 위치를 추정하는 것은 회귀 작업으로 가능
- 물체를 둘러싸는 바운딩 박스를 추정하는 방법
- 바운딩 박스를 예측하는 일반적인 방법은 물체 중심의 수평, 수직 좌표와 높이, 너비를 예측하는 것 (= 네 개의 숫자 예측)
일반적으로 전역 평균 풀링 층 위에 네 개의 유닛을 가진 두 번째 밀집 출력층을 추가하고 MSE 손실을 사용해 훈련
base_model = keras.applications.xception.Xception(weights="imagenet",
include_top=False)
avg = keras.layers.GlobalAveragePooling2D()(base_model.output)
class_output = keras.layers.Dense(n_classes, activation="softmax")(avg)
loc_output = keras.layers.Dense(4)(avg)
model = keras.models.Model(inputs=base_model.input,
outputs=[class_output, loc_output])
model.compile(loss=["sparse_categorical_crossentropy", "mse"],
loss_weights=[0.8, 0.2], # 어떤 것을 중요하게 생각하느냐에 따라 지정
optimizer=optimizer, metrics=["accuracy"])
바운딩 박스를 추정하기 위해서는, 데이터가 바운딩 박스 레이블을 가지고 있어야함
꽃 데이터셋은 꽃 주위에 바운딩 박스를 가지고 있지 않음
- 레이블을 만드는 것은 많은 비용이 드는 작업
- 이미지에 바운딩 박스를 추가하기 위해 오픈소스 이미지 레이블 도구나
- 이미지가 매우 많다면 크라우드소싱 플랫폼을 고려해볼 수 있음
꽃 데이터셋의 모든 이미지에 대해 바운딩 박스가 준비되어있다고 가정
- 클래스 레이블, 바운딩 박스와 함께 전처리된 이미지의 배치가 하나의 원소인 데이터셋을 만들어야함
- 각 원소는 (images, (class_labels, bounding_boxes)) 형태의 튜플이 됨
모델 훈련시 손실함수로 MSE 외에, 좋은 지표로 IoU사용
- 바운딩 박스를 얼마나 잘 예측하는지 평가하는 데 널리 사용됨
- IoU값은 예측한 바운딩 박스와 타깃 바운딩 박스 사이에 중첩되는 영역을 전체 영역으로 나눈 것
- tf.keras.metrics.MeanIoU에 구현
14. 9 객체 탐지
객체 탐지는 하나의 이미지에서 여러 물체를 분류하고 위치를 추정하는 작업
이전에 널리 사용되던 방법은 하나의 물체를 분류하고 위치를 찾는 분류기를 훈련한 후, 이미지를 모두 훑는 것
- 이미지를 6x8 격자로 나누고 하나의 CNN이 모든 3x3 영역을 지나감
- 스텝을 이동면서 이미지의 물체를 감지함
- CNN이 전체 이미지를 슬라이딩하면서 모든 3x3 영역을 보게되고,
- 3x3 영역이 끝나면 CNN이 4x4 영역도 슬라이드할 수 있음
- 쉬운 방법이지만, 조금씩 다른 위치에서 동일한 물체를 여러 번 감지함
- 불필요한 바운딩 박스를 제거하기 위해 사후처리가 필요함 - NMS
- CNN에 또 다른 꽃이 정말 이미지에 존재하는지 확률을 추정하기 위해 존재여부(confidence) 출력을 추가
- 존재여부 점수가 어떤 임계값 이하인 바운딩 박스를 모두 삭제 - 실제 꽃이 들어 있지 않은 바운딩 박스가 모두 삭제됨
- 존재여부 점수가 가장 높은 바운딩 박스를 찾고, 이 박스와 많이 중첩된(ex. IoU가 60% 이상인) 다른 바운딩 박스를 모두 제거
- 더는 제거할 바운딩 박스가 없을 때까지 3번째 단계를 반복
출처: https://towardsdatascience.com/non-maximum-suppression-nms-93ce178e177c
- 이런 간단한 객체 탐지 방식은 잘 동작하지만 CNN을 여러 번 실행시켜야 해 많이 느림
- 완전 합성곱 신경망(FCN)을 사용해 CNN을 빠르게 이미지에 슬라이딩시킬 수 있음
14. 9. 1 완전 합성곱 신경망 (FCN, Fully Convolutional Networks)
2015년 시맨틱 분할을 위한 논문에서 소개된 아이디어
CNN 맨 위의 밀집 층을 합성곱 층으로 바꿀 수 있음
- 7x7 크기 512개의 특성 맵을 출력하는 합성곱 층 위에 뉴런이 4096개 있는 밀집 층이 있을 때
- 각 뉴런은 합성곱 층에서 출력된 512x7x7 크기의 활성화 값과 편향에 대한 가중치 합을 계산함
- 이 밀집 층을 7x7 크기의 필터 4096개와 "valid" 패딩을 사용하는 합성곱 층으로 바꾸면
- 이 층은 1x1 크기의 특성 맵 4096개를 출력할 것 (커널이 입력 특성 맵 크기과 같고, 패딩 없음)
- 즉, 밀집 층과 같이 4096개의 숫자가 출력되는 것
- 밀집 층의 출력은 [배치 크기, 200] 크기의 텐서 / 합성곱 층은 [배치 크기, 1, 1, 200] 크기의 텐서
- 밀집 층은 특정 입력의 크기를 기대하지만, 합성곱 층은 어떤 크기의 이미지도 처리 가능
- FCN은 합성곱 층(그리고 동일한 성질인 풀링 층)만 가지므로 어떤 크기의 이미지에서도 훈련/실행 가능
- 꽃 분류와 위치 추정을 위해 하나의 CNN을 훈련했다고 가정
- 이 모델은 224x224 이미지에서 훈련했고, 10개의 숫자를 출력
- 0~4번째 출력은 소프트맥스 활성화 함수로 전달되어 클래스마다 하나씩 클래스 확률을 만듦(5개 클래스)
- 5번째 출력은 로지스틱 활성화 함수를 통과하여 존재여부 점수를 출력
- 6~9번째 출력은 바운딩 박스의 좌표와 높이, 너비를 나타냄
- => 이 밀집 층을 합성곱 층으로 바꿀 수 있음
- 이 네트워크에 224x224 크기 이미지가 주입되었을 때 출력 층 직전의 합성곱 층이 7x7 크기 특성 맵을 출력한다고 가정
- 이 FCN에 448x448 크기 이미지를 주입하면 병목 층은 14x14 크기 특성 맵을 출력할 것
- 밀집 출력 층이 7x7 크기의 필터 10개와 "valid" 패딩, 스트라이드 1을 사용한 합성곱 층으로 바뀌었기 때문에 출력은 8x8 크기(14-7+1=8)의 특성 맵 10개로 이루어짐
- 즉 FCN은 전체 이미지를 딱 한 번 처리하여 8x8 크기의 배열을 출력함(각 셀은 10개의 숫자를 가짐)
- 원래 CNN이 행 방향으로 8스텝, 열 방향으로 8 스텝 슬라이딩하는 것과 같음 -> 여러번의 예측
- 이런식으로 동일한 합성곱 신경망으로 작은 이미지와 큰 이미지를 처리할 수 있음
14. 9. 2 YOLO
2015년 제안된 매우 빠르고 정확한 객체 탐지 구조
- 이후 2016년 YOLOv2, YOLOv3 에서 향상됨
- 매우 빠른 알고리즘으로 실시간 비디오에 적용 가능
YOLOv3 구조
- 앞서 설명한 구조와 비슷하지만, 각 격자 셀마다 1개가 아닌 5개의 바운딩 박스 출력
- 바운딩 박스마다 하나의 존재여부 점수가 부여됨
- 20개 클래스가 있는 PASCAL VOC 데이터셋에서 훈련되었기 때문에 격자 셀마다 20개의 클래스 확률을 출력
- 즉, 격자 셀마다 총 45개의 숫자가 출력됨 : 4개의 좌표를 가진 5개의 바운딩 박스, 5개의 존재여부 점수, 20개의 클래스 확률
- 바운딩 박스 중심의 절대 좌표 예측이 아닌 격자 셀에 대한 상대 좌표 예측
- (0, 0)은 셀의 왼쪽 위, (1, 1)은 오른쪽 아래를 나타냄
- 각 격자 셀에 대해 바운딩 박스의 중심이 격자 셀 안에 놓인 것만을 예측하도록 훈련
- 로지스틱 활성화함수를 적용하여 바운딩 박스 좌표가 0~1 사이가 되도록 만듦
- 신경망을 훈련하기 전에, YOLOv3는 앵커 박스(사전 바운딩 박스)라 부르는 5개의 대표 바운딩 박스 크기를 찾음
- 이를 위해 k-평균 알고리즘을 훈련 세트 바운딩 박스의 높이와 너비에 적용
- ex. 훈련 이미지에 보행자가 많다면 앵커 박스 중 하나는 전형적인 보행자 크기가 될 것
- 그 다음, 신경망이 격자 셀마다 5개의 바운딩 박스를 예측할 때 각 앵커 박스의 스케일을 얼마나 다시 조정할 것인지 예측
- ex. 한 앵커 박스의 길이가 100픽셀/너비가 50픽셀이라면 네트워크가 수직 방향 스케일 조정 비율을 1.5/수평 조정비율을 0.9로 예측 - 예측되는 바운딩 박스 크기는 150x45 픽셀이 됨
- 적절한 차원의 바운딩 박스를 예측할 가능성을 높여줌
- 네트워크가 다른 스케일을 가진 이미지를 사용하여 훈련됨
- 훈련하는 동안 몇 번의 배치마다 랜덤하게 새로운 이미지 차원을 선택함(330x330~608x608픽셀)
- 이를 통해 네트워크가 다른 스케일의 객체를 감지하는 방법을 학습함
- 또한 YOLOv3를 다른 스케일에 사용할 수 있음 - 작은 스케일은 정확도가 떨어지지만 속도가 빠름
추가로, 2016년 YOLO9000 모델은 WordTree라 부르는 시각 계층의 각 노드에 대한 확률을 예측함
- 이 네트워크는 개의 품종은 몰라도 이미지가 개를 나타낸다고 확신을 가지고 예측할 수 있음
- detection 데이터셋의 레이블은 20~몇 백개 정도가 전부(common objects & general labels like 'dog' or 'boat')인 반면
- classification의 데이터셋은 클래스가 매우 많음(dog - bedlington terrier & Yorkshireterrier)
=> 이런 gap을 해결하고 많은 양의 클래스를 detect하고자함
- 방대한 크기의 class에 대한 분류를 위해 계층적으로 분류 작업을 수행해야한다고 제시
- 데이터가 (dog)-(bedlington terrier, Yorkshireterrie,...)와 같은 계층적 레이블을 가질 때 softmax 연산 수행시 전체 클래스에 대해 한 번에 수행하지 않고, 각 대분류 별로 softmax를 수행할 것을 제안
- wordtree를 이용하여(계층 구조를 도입해서) ImageNet classification 과 coco 데이터셋을 합친 총 9418개의 클래스를 가진 데이터셋을 생성
- 이 중 9000개는 ImageNet classification 데이터
- ImageNet classification은 분류 레이블만 존재
- coco 데이터셋은 Object Detection을 위한 레이블 존재
- 학습과정에서 coco 데이터셋이 더 많이 샘플링 되도록하고, 분류 레이블만 붙어있는 이미지는 classfication loss만 역전파 되게끔 학습
=> classification, object detection 태스크가 섞여있는 데이터셋을 학습할 수 있음
=> 9000개가 넘는 object를 detect할 수 있음
mAP
객체 탐지에서 널리 사용되는 평가지표
- 정밀도/재현율 트레이드오프의 경우를 떠올렸을 때
- 한 분류기가 10% 재현율에서 90% 정밀도, 20% 재현율에서 96% 정밀도를 달성한다고 가정
- 이 경우는 트레이드-오프가 없음
- 10% 재현율에서 정밀도를 보는 것이 아니라 최소 10% 재현율에서 분류기가 제공할 수 있는 최대 정밀도를 찾아야함 (=> 96%)
- 따라서 공정한 모델의 성능을 측정하는 한 가지 방법은 최소 0% 재현율에서 얻을 수 있는 최대 정밀도, 그 다음 10%, 20%.. 100% 까지 재현율에서의 최대 정밀도를 계산한 후, 이 값을 평균하는 것
- => 평균 정밀도(AP, average precision)
- 두 개 이상의 클래스가 있을 때는 각 클래스에 대해 AP 계산 후 평균 AP 계산 => mAP
객체 탐지 시스템에서의 mAP
- 시스템에 정확한 클래스를 탐지했지만 위치가 잘못되었다면(바운딕 박스가 객체 밖으로 벗어났다면) 올바른 예측으로 포함시키지 않아야 함
- IOU 임계점을 정의하는 것이 방법
- ex. IOU>0.5 이고 예측 클래스가 맞다면 올바른 예측으로 간주
- 이에 해당하는 mAP는 일반적으로 mAP@0.5 라고 씀
- PASCAL VOC 같은 일부 대회에서는 이 값을 구하는 것이 목표
- COCO와 같은 대회에서는 다른 IOU 임계값(0.50, 0.60..., 0.95)에서 mAP를 계산하고 이 값을 모두 평균한 것이 최종 지표가 됨(mAP@[.05:.95]) -> 평균 mAP
쯔하오 짱, yolo 구현(tensorflow)
그 외 탐지 모델
SSD
YOLO와 비슷한 싱글 샷 탐지 모델
Faster R-CNN
이미지가 먼저 CNN 하나를 통과해 그 출력을 RPN이라는 네트워크 으로 전달
- RPN은 객체가 들어 있을 가능성이 높은 바운딩 박스를 추출
- 이 CNN의 출력을 기반으로 바운딩 박스마다 분류기를 실행
14. 10 시맨틱 분할
물체가 속한 클래스에 따라 이미지의 모든 픽셀을 분류하는 작업
- 각 픽셀은 픽셀이 속한 객체의 클래스로 분류됨
클래스가 같은 물체는 구별되지 않음
- 같은 클래스의 물체가 붙어있으면, 하나의 큰 픽셀 덩어리가 됨
시맨틱 분할에서 가장 어려운 점은 이미지가 일반적인 CNN을 통과할 때 점진적으로 위치 정보를 잃는 것(1 이상의 스트라이드를 사용하는 층 때문)
- 보통은 CNN은 이미지의 왼쪽 아래에 보도가 있다고 알 수 있지만 그보다 더 정확히 알지 못함
출처: https://ichi.pro/ko/indo-dolo-eseo-jayul-juhaeng-eul-wihan-simaentig-bunhal-27133034486845
앞서 말한 2015년 논문에서 단순한 해결 책이 제안됨
1. 사전 훈련된 CNN을 FCN으로 변환
- 이 CNN이 입력 이미지에 적용하는 전체 스트라이드는 32(1보다 큰 스트라이드 모두 더한 것)
- 이는 마지막 층이 입력이미지보다 32배나 작은 특성 맵을 출력한다는 것
2. 따라서 해상도를 32배로 늘리는 업샘플링 층을 하나 추가
- 업샘플링 방법
- 1. 이중 선형 보간 - 4배나 8배로 늘리는 데 적함
- 2. 전치 합성곱 층 - 이 층은 먼저 이미지에 빈 행과 열을 삽입하여 늘린 다음 일반적인 합성곱을 수행
- 선형 보간에 가까운 작업을 수행하도록 초기화할 수 있지만 훈련되는 층이기 때문에 훈련 과정에서 더 잘 학습될 수 있음
3. 정확도를 높이기 위해 아래쪽 층에서부터 스킵 연결 추가
- 32배가 아닌 2배로 출력 이미지를 업샘플링하고, 아래쪽 층의 출력을 더해줌
- 그다음 이 결과를 16배로 늘려 업샘플링하여 최종적으로 32배의 업샘플링을 달성함
- 이 방식은 풀링 층에서 잃은 일부 공간 정보를 복원함
- 비슷하게 두 번째 스킵 연결을 사용해 더 낮은 층의 세부 정보를 복원하여 최상의 구조를 만듦
- 요약하면, 원본 CNN이 다음 단계를 추가로 거침
2배 업샘플링 -> 아래쪽 층의 출력을 더함 -> 2배 업샘플링 -> 더 아래쪽 층의 출력을 더함 -> 8배 업샘플링
- 원본 이미지 크기보다 더 크게 업샘플링 가능 : 이미지 해상도 증가 , 초해상도
인스턴스 분할
시맨틱 분할과 비슷하지만 동일한 클래스 물체를 하나의 덩어리로 합치지않고 각 물체를 구분하여 표시(ex. 개별 자전거 인식)
- 현재 텐서플로 모델 프로젝트에 포함된 인스턴스 분할 모델은 Mask R-CNN
- 이 모델은 Faster R-CNN 모델을 확장하여 각 바운딩 박스에 대한 픽셀 마스크를 추가로 생성
- 물체마다 클래스 추정 확률과 바운딩 박스를 얻는 것뿐만 아니라 바운딩 박스 안의 물체의 픽셀을 구분하는 픽셀 마스크도 얻을 수 있음
딥러닝을 사용한 컴퓨터 비전 분야는 빠르게 발전하고 있으며, 합성곱 신경망을 기반으로한 구조가 계속 생기고 있음
- 적대적 학습, 설명 가능성, 현실같은 이미지 생성, 싱글 샷 학습 등
- 새로운 구조인 캡슐 네트워크
참조
FCN : Fully Convolutional Networks for Semantic Segmentation
openaccess.thecvf.com/content_cvpr_2015/papers/Long_Fully_Convolutional_Networks_2015_CVPR_paper.pdf
YOLO
YOLO9000
IOU
www.pyimagesearch.com/2016/11/07/intersection-over-union-iou-for-object-detection/
Transposed Convolution Upsampling
towardsdatascience.com/what-is-transposed-convolutional-layer-40e5e6e31c11
'AI > Hands-on ML' 카테고리의 다른 글
[핸즈온 머신러닝] 15장(2) - RNN과 CNN을 사용해 시퀀스 처리하기 (긴 시퀀스) (0) | 2021.04.27 |
---|---|
[핸즈온 머신러닝] 15장(1) - RNN과 CNN을 사용해 시퀀스 처리하기 (0) | 2021.04.26 |
[핸즈온 머신러닝] 14장(3) -케라스를 통한 CNN 구현 및 모델 사용 (0) | 2021.04.03 |
[핸즈온 머신러닝] 14장(2) - CNN 구조 (LeNet-5, AlexNet, GoogLeNet, VGGNet, ResNet, Xception , SENet) (0) | 2021.04.01 |
[핸즈온 머신러닝] 14장(1) - 합성곱 신경망을 사용한 컴퓨터 비전 (0) | 2021.03.21 |