감정인식팀이 지금까지 진행한 프로젝트에 대해 정리해봤습니다.
올해 은익체전이 취소되서 원래 목표했던 행사는 진행하지 못해서 아쉽네요~.~
감정인식 프로젝트를 계획.
단순히 감정을 인식하는 것보다 이를 게임이나 미션으로 연관시키면 흥미를 더 끌 수 있을 것으로 보고 게임으로 구현하기로 함
‘웃음참기'와 같이 여러가지 영상 시청 후 표정 변화가 없을 수록 높은 점수를 받는 미션을 진행하기로 결정했고
이 영상에서와 같이 실시간으로 인물의 표정을 통해 감정을 인식
MobileNet은 컴퓨터 성능이 제한되거나 배터리 퍼포먼스가 중요한 곳에서 사용될 목적으로 설계된 CNN 구조
기존의 Convolution Layer는 너무 무겁다! Small DNN을 만들자
MobileNetv2는 Depth-wise Separable Convolution, 그리고 Linear bottleneck을 갖는 inverted residual 모듈을 제안.
이 모듈은 낮은 치원의 압축된 표현을 입력으로 받아 높은 차원으로 먼저 확장한 뒤,
depth-wise convolution 필터를 통과시키고, linear convolution을 통해 다시 낮은 차원 표현으로 projection하는 과정을 거침.
Depth-wise Separable Convolution는 계산복잡도와 사이즈를 줄이면서도 conv 층의 표현력(expressiveness) 을 유지하기 위해 고안된 방법
보통의 convolution 연산이 input(3*3*3) -> output(1) 으로 한번에 수행할때,
depthwise convolution은 intput(3*3 + 3*3 + 3*3) -> output(1 + 1 + 1)
pointwise convolution은 input(1 + 1 + 1) -> output (1)
따라서 기존의 Convolution은 채널과 필터가 동시에 고려돼 최종 아웃풋을 만듦.
이게 가능한 이유는 Xception의 핵심가설때문인데
cross-channels correlation(입력 채널(이미지들)들 사이의 유사도)과 spatial correlation(필터와 하나의 특정 채널 사이의 관계. 즉 필터가 이미지의 특성을 잘 포착하는 정도)이 완전하게 독립적이기 때문에 채널과 필터를 따로 분리해서 학습을 진행해도 문제가 없다고 주장함.
입력 채널을 변형(압축)해서 넣어도 성능에는 크게 영향이 없다는 것으로 해석가능
즉 전체에 대한 Convolution이 일반적인 연산이라면 이를 채널 별로 Convolution + 1x1 채널 간 Convolution 으로 Factorization 한 것.
실제로 연산량을 계산해보면 기존의 convolution의 연산량은 입력 이미지의 크기x입력 이미지의 채널x 커널사이즈 제곱x아웃풋채널 이지만 Depthwise Separable Convolutions의 연산량은 입력 이미지의 크기x입력 이미지의 채널x (커널사이즈 제곱+아웃풋채널) 이기 때문에 8~9배 정도 연산량이 줄어듦. (커널 사이즈는 3 이라고 가정함)
Bottleneck Architecture는 일반적으로 pointwise 1x1 Conv를 이용해 Channel Reduction(차원 수를 줄임)을 하는 방식
입력 채널 정보를 activation space에 전부 담지 못하는 현상이 발생하는데 이는 Relu함수의 비선형에 의한 정보손실로 인해 발생합니다
(0이하의 값을 가진 경우 0으로 맵핑) 또한 연산량을 줄이기 위해서 1*1 conv 로 과도하게 압축하다보니 역시 정보손실이 생깁니다.
Input Manifold가 Activation Space보다 작은 차원의 subspace로 embedding이 가능하면,
Non-linear Activation에 의한 변환이 정보를 잃지 않으면서 표현력이 좋은 함수처럼 작동한다고 해석
manifold란 어떤 이미지의 차원들이 존재하는 공간 -> 고차원의 정보는 사실 저차원으로 표현이 가능함
예를 들어서 설명하면, 실제 세상에 존재하는 모든 사물들은 3차원 이라고 이야기를 하지만 사람들은 실제로 사물을 구분할 때는 2차원 정보를 받아들여 사물을 구분할 수 있다는 것으로, 즉 고차원 정보는 사실 저차원 정보로도 충분히 구분할 수 있다는 것.
Linear Bottlenecks을 만들 때 1x1의 pointwise Convolutions을 하여 차원수를 줄이는 것은 Manifold의 가설 그대로 ‘고차원의 채널은 사실 저차원의 채널로 표현할 수 있다’ 라는 논리 전개. => ‘채널수가 충분히 많으면 ReLU를 사용해도 중요 정보는 보존된다!’
Depth-wise Separable Convolutions과 Linear Bottlenecks을 결합하면 Inverted Residuals 모듈
residual connection은 ResNet과 동일하게 gradient를 더 잘 전달하기 위함임
기존의 Residuals을 거꾸로 뒤집은 모양.
앞에서 언급한 논리대로 ReLU를 사용해야 하기 때문에 채널을 확장(pointwise Convolutions)하고 Depthwise Convolutions을 진행.
또 Linear Bottlenecks에서 다시 채널 수를 줄임.
Input으로 low-dimensional compressed representation을 받아 high-dimension으로 확장시킨 후,
depthwise convolution을 수행. 이렇게 나온 feature를 다시 linear-convolution을 통해 low-dimensional 정보로 만듦.
즉, narrow-wide-narrow의 형태.
이러한 Module(Inverted Residual Block) 덕분에 Memory 사용량이 줄어, mobile design에 최적화 됨
One-stage detector
Localization과 classification을 한번에 하고 Bounding box와 classification을 regression 문제로 만든다.
이미지를 NxN의 구역으로 나누어 각 그리드의 중심을 중심으로하는 앵커박스를 제안해 물체를 탐지한다.
앵커박스의 너비(Pw)와 높이(Ph)에 자연함수를 곱해 bw,bh로 보정을하고 중심좌표는 시그모이드를 취해 보정한다.
K means clustering을 통해 데이터셋에서 물체의 모양들을 9개의 크기로 분류하여 앵커박스의 크기로 설정함
레이어를 거칠때마다 피처맵 사이즈는 줄어들고 피쳐에 대한 정보는 잘 정제됨
위와 같이 다른 앵커박스로부터 같은 물체에 대해 다수의 중첩이 발생한다.
가장 높은 confidence값을 가지는 박스와 IoU가 0.5이상이면 지우고 0.5이하이면 다른 물체로 판단한다.
최종적으로 한 물체당 하나의 박스만 가지게 된다.
-detection
특징추출기(여기선 darknet-53)를 지나 특징이 잘 정제된 피쳐맵을 2배로 업스케일링하는 과정을 두번 반복하여 3가지 스케일의 피쳐맵을 만들고 가장 작은 피쳐맵에서 가장 큰 물체를 탐지하고 점점 작은 물체를 탐지한다. 이때 앵커박스는 앞서 k-means clustering을 통해 정한 것을 작은 크기부터 3개씩 나누어 피쳐맵 크기별로 적용한다.
-위치정보
특징추출이 끝난 피쳐맵은 크기가 많이 줄어들어 위치정보가 부족하므로 특징 추출 과정에 있었던 피쳐맵의 위치정보를 가져와서 사용한다.
Backbone은 MobileNet 으로 진행하였음. 우리가 작성한 코드를 보면
이렇게 되어있는데 이때 weights는 imagenet으로 학습된 것을 가져온다고 작성하였음.
imagenet은 기본 label 1000개를 갖는 사진 1,281,167장의 이미지를 가진 데이터 셋을 의미함.
기본 데이터의 개수는 저 수치가 맞지만 일반적으로 네트워크에 학습시킬 때 mini-batch사이즈를 설정하고 epoch만큼 돌리며, 각각 실행시킬 전체갯수도 정해 학습함
dataset을 생성시키기 위한 generate부분을 봐줘야함.
왜냐하면 기본적으로 network의 구조에 맞춰서 data를 집어 넣어야 하기 때문임.
따라서 입력데이터의 사진들의 사이즈를 입력구조(224x224 -> mobilenet 설계상 그렇다)에 맞춰 변형시켜야함.
일반적으로 옛날 CNN강의들을 보면 알지만 좋은 학습을 위해 사진들을 더 많이 집어넣어서 학습하는데 여기서도 참고할 점은 정형화된 사진들만을 학습시키지 않기 위해 반전, 회전되는 이미지도 입력으로 넣어야하고rescale과정도 첨가(0~255의 rgb값이 0~1로 변환)등등의 성능을 얻기 위한 좋은 입력 데이터를 생성하려고 작성되어있음.
이를 바탕으로 학습을 위한 batch-size, epoch등의 변수값을 통해 학습 과정에 이용될 수 있는 데이터 묶음이 되며 이는 일종의 학습 데이터 전처리과정이라고 볼 수 있음
프로그램을 실행하면 웃긴 영상(Happy)/공포 영상(Surprise) 모드 선택 기능
모드에 따라 얼굴 인식 프로그램 시작
얼굴을 인식해서 모드와 일치하는 감정점수가 일정 점수 이상 나오고,
튀는 현상을 막기 위해 유지시간에 대해서도 일정 시간 이상의 threshold를 걸어준다.
조건을 만족하면 진 것으로 하고, 아니면 이기거나 다음 단계로 넘어간다.
프로그램을 실행하면 웃긴 영상(Happy)/공포 영상(Surprise) 모드 선택 기능
그 다음 레벨(1,2,3)중 선택 가능
선택된 모드, 레벨의 영상들 중 랜덤 재생
MobileNet – V2
Yolo – V3
BackBone Net - MobileNet / Detection – Yolo
깃허브의 올라온 구조인데 보면 가장 상단에 convolution이라고 이라고 사용되고 있음. 아마 저 convolutional 밑에 사용된 filter, stride 등의 정보를 갖고 convolution을 진행하는 다크넷 버전의 함수를 만든 것으로 판단
conv2D함수를 다크넷 구조의 convolution으로 덮어쓴다는 의미임.
args는 어떤 여러 개의 데이터를 의미하고
kwargs는 뉴럴넷 상의 변수들(가중치,패딩,stride 등)을 의미하는 듯 보임.
넘겨받은 두개의 데이터를 가지고 다크넷 버전의 kwargs(뉴럴넷 변수)를 만듬.
첫번쨰 라인은 regularization을 위한 변수를 등록,
두번째 라인이 stride변수에 저장된 값이 (2,2)라면 padding 변수를 비활성화한다라는 의미
(valid는 no padding, same은 input size에 맞춰 ouput도 padding으로 맞춰주는 옵션이다).
아마 convolution개념 그 자체를 의미해서 압축하는 개념인 것으로 생각되고 stride가 (1,1)(3,3)인 경우는 크기를 다시 맞춰주는 옵션을 수행하게 됨.
이 전체 코드를 보기 전에 우리는 github에 있는 코드 중에 yolo-body구조를 봐야함
yolo는 기본적으로 다크넷 기반에도 동작하기 때문에 앞에서 여러 개의 다크넷 버전의 함수를 선언한것.
그리고 무엇보다 처음에 다크넷에서 입력받게 되지만 우리는 모바일 넷에서의 결과를 input으로 yolo에 넣어야 한다.
그렇기 때문에 모바일넷에서 결과를 가져와줘야 함.
mobilenetV2함수는 첫번째 인자는 입력 이미지를 의미함, 두번째 인자는 이 모바일넷의 weight학습을 의미함. (none이면 랜덤으로 초기화를 하고 여기처럼 imagenet을 하면 ImageNet data set으로 미리 학습된 가중치를 사용하게 됨.) 세번째 인자는 내가 모바일넷 상단 시작을 fully connected로 설정할 것인지에 대한 여부를 의미. 그러면 이 의미는 백본으로 이미 학습된 모바일 넷을 가져온 것이다.
기본적으로 get_layer는 keras에서 제공하는 api함수로 해당하는 레이어의 이름이나 index의 레이어의 instance를 리턴해주고
Output은 텐서를 도출해주는 역할로 결론적으로 ‘out relu’라는 이름의 계층의 instance의 output 텐서를 저장함
out_relu는 keras mobilenet.py를 보면 볼수가 있는데 relu를 통과한 feature map을 뜻하게 되어 우리가 다크넷 대신에 모바일넷을 거쳐서 나온 결과 벡터행렬 값을 받아오는 것이다.
이 그림에서 저 빨간 부분에서 데이터를 가져오는 부분에 해당하게 된다. 앞서 말했던 대로 다크넷 기반이 아닌 모바일넷 기반이기 때문에 저렇게 결과 layer의 출력값만 f2로 가져와서 이어지는 concatenate를 위해 저장
이 함수는 레이어를 합치는 함수임, 인자로 리스트형식의 tensor를 전달하는데 이때 최소 2개를 전달해야 함.
이어지는 나머지 부분인데 이 설명들은 앞선 yolo구조의 나머지 부분에 해당
'3.5기(200104~) > 감정인식' 카테고리의 다른 글
감정인식팀 6주차 Code Review (0) | 2020.04.25 |
---|---|
6주차_20/04/06_감정인식 프로젝트 (0) | 2020.04.11 |
감정인식팀 5주차 (0) | 2020.04.03 |
감정인식팀 4주차 (0) | 2020.03.28 |
3주차_Keras로 구현된 간단한 MobileNet 코드 리뷰 및 학습 시키기 (0) | 2020.03.21 |