🏭

BridgeNet: A Continuity-Aware Probabilistic Network for Age Estimation

Tags
Age Estimation
Created
2021/01/31 08:36
Publication
CVPR'19
Rate
2.8
Source
https://arxiv.org/abs/1904.03358
Summary
(상세 페이지 참고)
CVPR 2019에 accept된 age estimation 모델이다. Age estimation에서 가장 큰 화두는 바로 나이를 먹는 과정은 (겉으로 보기에) 연속적이면서도 나이대에 따라 그 양상이 크게 다르다는 것이다. 예컨대 비슷한 나이대의 얼굴들은 (나이의 관점에서) 굉장히 비슷해보이지만, 10대의 성장 양상은 주로 얼굴 모양 등에서 발생하는 반면 4~50대의 성장 양상은 얼굴의 미세한 주름 등에서 발생하기 마련이다. 많은 age estimation에 관한 페이퍼들이 이러한 문제에 맞는 형태의 모델 구조를 찾아내기 위해 노력한다. 대표적인 줄기를 꼽아보자면 1) regression, 2) ordinal regression, 3) classification 등이 있겠다.
하지만 페이퍼에서는 이러한 모델들이 연속성과 이질성을 동시에 다뤄내는 데 실패했다고 주장하며, 이를 해결하기 위한 BridgeNet 모델 구조를 제안한다.
BridgeNet 구조는 feature extraction(페이퍼에서는 VGG-16을 사용한다) 이후 두 branch로 나뉘는데, 바로 local regressor와 gating network이다. BridgeNet에서는 이질적인 데이터를 동질적인 kk 개의 그룹으로 나누고, 그룹 내에서 다시 세부적인 나이를 예측하는 divide-and-conquer 방식을 따르는데, local regressor는 conquer를 담당하는, 즉 동질적인 데이터를 포함하도록 나뉘어진 그룹 내에서의 세부적인 나이를 예측하기 위한 regression branch이며, gating network는 divide를 담당하는, 즉 간단히 말하자면 주어진 데이터를 kk 그룹에 할당하는(?) branch라고 볼 수 있겠다.
다음의 수식을 보면 이러한 모델의 구조가 보다 쉽게 이해된다. 임의의 그룹 l=1,2,...,kl = 1, 2, ..., k에 대해, 어떤 데이터 xx에 대한 나이 yy의 확률을 다음과 같이 표현할 수 있다.
p(yx)=lπl(x)N(yμl(x),σl2)p(y | x) = \sum_{l}{ \pi_l{(x)} N(y | \mu_l{(x)}, \sigma_l^2) }
여기서 πl(x)\pi_l{(x)}는 데이터 xx가 그룹 ll에 속할 확률이며, 뒤의 N()N()은 해당 그룹 내에서 데이터가 해당 나이를 가질 확률이다. 이제 yy의 기댓값을 다음과 같이 구해볼 수 있겠다. (페이퍼에서는 굉장히 두루뭉술하게 써 놓았는데... 맞나? 제정신일 때 검토 필요.)
E(yx)=yyp(yx)=yylπl(x)N(yμl,σl2)=lπl(x)yyN(yμl,σl2)=lπl(x)μl(x)E(y | x) = \sum_y{ y p(y | x) } \\ = \sum_y{ y \sum_l{ \pi_l{(x)} N(y | \mu_l, \sigma_l^2) } } \\ = \sum_l{ \pi_l{(x)} \sum_y{ y N(y | \mu_l, \sigma_l^2) } } \\ = \sum_l{ \pi_l{(x)} \mu_l(x) }
이제 위 식의 πl(x)\pi_l{(x)}가 gating network의 output, μl(x)\mu_l(x)가 local regressor의 output이다.

Local Regressor

그렇다면 local regressor는 어떻게 구현하면 좋을까? 별 거 없고, 그냥 kk 개의 output을 가진 FC layer를 통해 구현한다. 즉 각각의 output node 값에 sigmoid를 씌우고, 이를 그룹 내 값에 맞도록 변환하는 것이다. 예컨대 첫 번째 그룹이 0~25, 두 번째 그룹이 15~40, ..., 이런 식으로 된다면, linear layer의 output의 첫 번째 값은 0~1 사이의 값이 될 터인데, 여기에 25를 곱하고, 두 번째 값은 25를 곱한 후 15를 더하고, ..., 이런 식이다. (확실하지 않다. 이 부분에 대한 자세한 설명이 나와있지 않다.)
여기서 눈여겨 볼 점은, 1) 각각의 그룹의 중앙값들은 전체 나이의 범위에 대해 균일하게 분포하도록 하였다는 것이고, 2) 나이를 먹는 과정의 연속성을 반영하기 위해 연속된 그룹이 포함하는 나이의 범위가 서로 겹치도록(densely overlapping) 그룹을 설정하였다는 것이다.

Gating Networks

πl(x)\pi_l{(x)}를 구하기 위해서는 트리 구조를 사용한다. 그런데 그냥 트리 구조를 사용하지 않고, 역시나 연속성을 반영하기 위해 node의 양 끝 leaf를 인접한 node의 leaf와 연결한 bridge tree 구조를 사용한다. 그림으로 보는 것이 편하니 자세한 이해를 위해서는 페이퍼에 첨부된 이미지를 확인하는 것이 좋다.
이러한 트리 구조를 구현하기 위해서도 역시나 FC layer를 사용하는데, FC layer의 node 하나를 트리 구조의 edge에 할당한다. 하나의 노드에 연결된 leaf들의 합은 1이어야 하는 것이 합리적이므로, 해당되는 노드들을 묶어서 softmax activation을 통해 그 값을 구한다. 당연히 prediction leaf(가장 밑에 있는 leaf들)의 수는 kk가 되어야 하겠다. 최종적으로 πl(x)\pi_l{(x)}를 구하기 위해 해당 leaf로 향하는 경로의 확률들을 더한다.
이제 regression loss는 다음과 같이 구한다.
Lreg(x,y)=lLIl(x,y)(yμl(x))2L_{reg}(x, y) = \sum_{l \in L}{ I_l{(x, y)} (y - \mu_l{(x)})^2 }
위에서 Il(x,y)I_l{(x, y)}는 target yy가 그룹 kk에 속하는지 여부를 나타내는 함수이다. 즉 해당되는 그룹의 local regressor에만 L2 loss를 부과한다고 보면 되겠다.
또 gating loss를 구해야겠는데, 먼저 target을 다음과 같이 지어낼 필요가 있다.
π^l(x)=Il(x,y)lIl(x,y)\hat{\pi}_l(x) = \frac{ I_l{(x, y)} }{\sum_l{ I_l{(x, y)} }}
그러면 $p(l | x)$와 $\hat{\pi}l(x)$의 KL divergence를 gating loss로 한다.
Lgate(x,y)=lLπ^l(x)logπl(x)L{gate}(x, y) = -\sum_{l \in L}{ \hat{\pi}_l{(x)} \log{ \pi_l{(x)} } }
그리하여 최종 loss를 L=Lreg+λLgateL = L_{reg} + \lambda L_{gate}와 같이 구하여 학습이 가능하다!
나도 최근에 divide-and-conquer 방식에 대해 꽤 고민을 많이 하고 있던 터라(그리고 대충 하나 뚝딱 만들어서 학습해보니 성능이 엉망이었던 경험이 있던 터라) 반가우면서도 호기심이 많이 드는 페이퍼이다. 어쨌거나 요약하자면, divide-and-conquer 방식을 통해 성장의 이질성을 다루고, 각각의 local regressor와 gating network에서 특정 구조를 통해 연속성을 다루고자 하는 age estimation 모델이다.
실험 내용을 보니, MORPH II, FG-NET, ChaLearn LAP 2015, IMDB-WIKI 등에서 안정적으로 SOTA를 달성한 듯하다. 하지만 마음에 걸리는 것은 OR-CNN이나 CORAL 등의 모델이 없다는 것이다. 심지어 간단히 찾아보니 구현체도 없는 것 같아, 직접 구현해봐야 할 것 같다.
E.O.D.