One shot learning, Siamese Network 이해


Problem Definition 


이미지 인식 분야에서 각 label 의 이미지 수가 적을 때 이를 인식하고 분류하는 것은 challenging 합니다. 예를 들어 얼굴 인식 분야에서는 단 몇 장의 이미지만을 통해 동일인인지 여부를 구분해야하는 문제가 있습니다. 물론 augmentation 과 같은 방법으로 샘플 수를 늘려서 CNN 으로 multi-class classification 문제를 풀도록 학습시키는 방법이 가능합니다. 하지만 이 경우, 새로운 사람이 데이터 베이스에 추가되었을 때, 모델을 새로 학습해야한다는 문제가 생깁니다. 즉, 실시간 시스템에 적합하지 않은 방법입니다. 


이러한 문제를 해결하는 한 가지 방법은 "Distance function" 을 이용하는 것입니다. 


D(x_1, x_2) = degree of difference between images 


Distance function 을 이용해, 예를 들어, D(Image1, Image2) <= k 인 경우 같은 사람이라고 예측하고, > k 인 경우 다른 사람이라고 예측할 수 있습니다. 또는 DB 에 있는 모든 Image 에 대해사 distance 를 계산한 후에 가장 distance 가 작은 사람으로 분류할 수 있습니다. 이러한 아이디어의 의미는 face recognition 에서는 누구인지 구분하는 것보다 "동일인지 여부" 가 중요하다는 것입니다. 또한 이를 이용해 multiclass classification 을 할 수도 있습니다. 이는 아이디어 측면에서 머신러닝의 고전적인 방법인 nearest neighbor 방법과 비슷합니다. 본 포스팅은 Distance function 의 인풋으로 넣기 위한 representation 을 만드는 함수 f 를 딥러닝으로 학습하는 방법에 관한 것입니다. 이미지의 distance 를 계산하기 위한 representation learning 개념입니다. 


Siamese Network + Triple loss


Our approach is to build a trainable system that nonlinearly maps the raw images of faces to points in a low dimensional space so that the distance between these points is small if the images belong to the same person and large otherwise. Learning the similarity metric is realized by training a network that consists of two identical convolutional networks that share the same set of weights - a Siamese Architecture (Sumit Chopra, 2005, CVPR)

함수 f 를 딥러닝 방법을 통해 학습할 수 있는 한 가지 방법은 Siamese network 을 이용하는 것입니다. Siamese network 는 2005년에 CVPR 에 발표된 방법으로, weights 를 공유하는 두 개의 CNN 입니다. 이 CNN은 Image1과 Image2를 f(Image1) 과 f(Image2) 라는 vector representation 으로 변환시킵니다. 그리고 f 를 학습시키기 위해 loss function 을 정의하고, distance 를 나타낼 수 있는 representation 을 만드는 방향으로 weights가 학습됩니다. 이미지1과 이미지2의 distance 를 f(Image1)과 f(Image2)의 l2 norm 으로 정의해봅시다. 


$$ D(x_1, x_2) = ||f(x_1) - f(x_2) || ^2 $$


loss function 으로 사용할 수 있는 한 가지는 Triplet loss 입니다. Triplet loss 는 3개의 이미지로부터 loss function 을 만드는 방법이며, 아이디어는 같은 사람의 이미지의 distance 가 다른 사람의 이미지의 distance 보다 작아지도록 하자는 것입니다. 이는 기술적으로  D(Anchor, Positive)D(Anchor, Negative) 보다 작아지도록 잡자는 것입니다. 이 때, Anchor 와 Positive 는 같은 사람의 다른 이미지이고, Negative 는 Anchor, Positive 와 다른 사람입니다. 이 때, alpha 라는 margin 을 주어 충분한 차이가 벌어지도록 합니다. 



이러한 아이디어를 이용해 실제로 정의되는 triplet loss 는 아래와 같습니다.


$$ L(A, P, N) = max(||f(A) - f(P)||^2 - || f(A)-f(N) || ^2 + \alpha, 0) $$


실제 배치 트레이닝시 loss 는 아래와 같이 계산될 것입니다. m 은 배치 샘플 수입니다. 


$$ J = \sum^{m}_{i=1} L(A^i, P^i, N^i) $$


Triplet loss 의 문제는, A, P, N 을 random 하게 골랐을 때, loss 가 0이 되는 것이 너무 쉽게 만족한다는 것입니다. 그래서 실제 트레이닝시 중요한 것은 구분하기 어려운 샘플을 고르는 것입니다. 즉, A-P 와 A-N의 distance 의 차이가 크지 않은 두 이미지를 우선적으로 사용하는 것이 좋습니다. 이 방법은 Triplet loss 를 제시한 논문에 설명되어 있습니다.  

https://omoindrot.github.io/triplet-loss


트레이닝 데이터에서 Triple loss 로 하나의 CNN 을 구현한 후 학습한 후, 테스트 데이터에서는 예를 들어, 이미지의 representation 을 얻은 후, DB 에 있는 representation 과의 distance가 k 미만일 때, 같은 사람이라고 verification 할 수 있습니다.


Siamese Network + Binary loss


아래와 같이 문제를 Binary classification 으로 formulation 해서 face recognition 을 구현할 수도 있습니다. 실제로 많이 사용하며, 성능도 괜찮은 방법입니다. 




https://medium.com/predict/face-recognition-from-scratch-using-siamese-networks-and-tensorflow-df03e32f8cd0


이 방법에서 Siamese Network 는 두 이미지를 input 으로 하고, 같은 사람을 1, 다른 사람을 0 로 encoding 된 label 을 통해 training 됩니다. triplet loss 를 사용한 방법에서는 max(l2 distance 의 차이+alpha, 0) 을 줄이는 방향으로 training 이 되었지만, binary classification 을 활용한 방법의 경우 구조가 약간다릅니다. 


Siamese network와 binary classification 을 결합한 방법에서 CNN 이후 아키텍쳐는 다음과 같습니다.  


1. 두 이미지에 대해 CNN 을 통과시켜 나온 두 representation 의 l1 vector 를 구합니다 (l1 vector는 CNN 으로 변환된 벡터의 absolute distance 를 원소로 갖는 vector 입니다).

2. l1 vector 를 hidden layer 에 통과시킨후 output layer 에서 sigmoid 변환을 합니다. 

3. Binary cross entropy 를 loss function 으로 모델을 학습합니다. 

4. 모델은 0-1 사이의 값을 갖는 output 내보냅니다. 이 값은 크면 클 수록 두 이미지가 비슷하다라는 것이므로 "similarity" 라고 할 수 있습니다. 

5. 이 과정을 거치면 X1, X2 에 대한 CNN 의 output representation f(X1), f(X2) 는 같은 사람에 대해서 distance가 작게, 다른 사람에 대해서는 distance 가 크게 나오게 됩니다. 



참고 


  • GyeongHo Kim 2021.01.29 15:48

    잘 읽었습니다 감사합니다