save the world

pca sparse coding #02 본문

PCA, Sparse Coding

pca sparse coding #02

함안조씨 2017. 1. 17. 15:41

PCA를 MATLAB으로 실습해보기 위하여 가장 많이 접하는 방법이 얼굴을 인식하여 복원하는 과정이다. 

그림 .1

  위와 같은 얼굴사진 1,000장을 Database로 가지고 있다고 가정해보자. 각각의 이미지가 100 x 100 의 크기를 가진다면 이를 concatenation 하여 10,000 x 1의 크기로 만들 수 있고, 이는 차원이 10,000인 데이터라고 할 수 있다. (즉, 각각의 이미지들은 차원이 10,000인 공간에서 하나의 점으로 볼 수 있다.) 이런 데이터들이 1,000장 있다면 이들을 가장 잘 분류 할 수 있는 차원이 있을 것이다. 이를 찾기위하여 1,000개의 데이터들에 대하여 PCA를 수행한다면, 차원의 갯수 10,000만큼의 주성분 벡터들을 얻을 수 있고 각각의 주성분 벡터들을 100 x 100으로 바꾸어 이미지로 본다면 아래와 같은 이미지들이 될 것이다.

그림. 1 Eigenface 15개

  위의 이미지들은 PCA를 수행하여 나온 벡터들 중 분산이 가장 큰 15개를 뽑아 eigenface1 부터 eigenface15까지 나열한 것이다. 이 eigenface들은 분산이 가장 큰 1번부터 15번까지를 나타낸다고 하였는데 이전의 글 http://tosavetheworld.tistory.com/21 #01글 마지막 부분에서 "어떤 데이터들이 분포하고 있을 때 이 데이터의 분산이 가장 큰 방향 하나만으로 데이터들을 표현하면 모든 방향으로 데이터를 표현한 것 보다는 정확하지 않지만(섬세하지 않지만) 표현이 가능하긴 하다." 라고 언급 했듯이 여기 있는 15가지의 주성분 벡터들을 이용하면 하나의 사람 얼굴을 묘사 할 수 있다는 것이다. 예를 들어서 그림. 1에서 첫번째 사람의 얼굴을 표현하기 위해서 15가지의 벡터들을 선형조합 한다면 첫번째 사람이 묘사 될 수는 있다는 것이다. (Ex. eigenface1 * 0.2 + eigenface2 * 0.08 + eigenface3 * 0.9 + eigenface4 * 0.05 * ... * eigenface15 * 0.1 = 첫번째 사람 이미지) 대신 10,000개의 벡터로 묘사한다면 그림.1 의 첫 번째 사람의 얼굴을 완벽히 똑같이 복원 할 수 있지만 굳이 그럴 필요 없이 15개의 주성분 벡터만으로 묘사 하자는 것이다.(그래야 빠르고 간단하게 대부분 사람들의 얼굴을 나타 낼 수 있으니까.) 참고로 eigenface 들을 분산이 큰 순서대로 나열했을때 뒤로 가면 갈수록 잡음이 많이 포함되어 더 이상 사람의 얼굴이라고는 볼 수 없는 이미지가 나오며 이 벡터(eigenface)는 주성분으로서의 역할을 한다고 보기는 어렵다. 그런 잡음이 많이 포함된 벡터(eigenface)는 #01에서 언급했던 PC3와 비슷한 이치가 된다.

  아래에서 첫번째 열을 보면 사람의 얼굴을 15개의 eigenface들로 복원한 이미지를 밑에서 볼 수 있다. 그리고 Original 이미지에 guassian noise, salt & pepper noise, 그리고 outlier를 포함한 이미지를 15개의 eigenface들로 복원했을 때의 이미지를 볼 수 있다.
 ※지금 15개의 eigenface들로 복원을하여 원래 첫번째 사람이 가진 얼굴의 특징이 잘 나오지 않았는데 eigenface들을 50개까지 올린다면 거의 원본과 비슷한 정도의 복원력을 볼 수 있다. 이는 그림.3 으로 추가하여 아래에 올렸다.

그림. 2 Eigenface 15개 사용

  위의 그림에서 outlier가 추가된 이미지를 복원하였을때의 결과를 보면 빨간색 동그라미 부분이 다른 복원된 이미지 보다 약간 어둡게 나왔는데 이는 eigenface들에서 outlier가 있는 영역이 까맣게 잘 나타나도록 eigenface 들을 선형 조합 하였기 때문에 복원 결과도 outlier 부분이 약간 어둡게 나온것이다. 그림.3 도 outlier image가 복원된 것을 보면 그림. 2와 비슷한 결과를 볼 수 있다.

그림. 3 Eigenface 50개 사용

이제 MATLAB을 이용하여 PCA를 어떻게 수행했는지 보자.(용량이 커서 분할 압축하였음.) PCA를 위하여 사용한 데이터는 Yale face database 이며 얼굴영역만 자른 이미지들이다. 사람은 38이 나오고 빛의 방향을 64가지로 나누어 사진을 사람당 64장 찍었다. 그래서 사진의 수는 총 2432개가 되며 추가적으로 조명이 하나도 없는 이미지를 사람마다 찍어 ambient 라는 이름으로 저장되어있다. 이 ambient가 있는 이유는 사진이미지를 그대로 쓰지않고 다른 조명이 잘 나온 사진에서 ambient를 뺀 것을 사용하기 위함이다. (이렇게도 쓴다고 한다. 그러나 저는 ambient를 사용하지 않았습니다.)

CroppedYale.vol1.eggCroppedYale.vol2.eggCroppedYale.vol3.eggCroppedYale.vol4.eggCroppedYale.vol5.eggCroppedYale.vol6.eggpca_prac_prof.zip

위 7개의 파일을 모두 받고 Croppedyale이라는 폴더에 각각의 yale01 02... 38 들을 모두 저장 한 후 Croppedyale 폴더가 있는 경로(Croppedyale 안에 말고)에 m 파일을 저장한다.

1. load section은 CroppedYale폴더에 있는 2432장의 이미지들을 모두 불러와서 concatenation 하는 과정이다.
2. section은 concatenation 된 2432개의 이미지들이 이미지 순서대로 차곡차곡 쌓여있기 때문에 이를 랜덤한 이미지 순서로 섞어주고 이 이미지들의 전반부 80%는 train 이미지로 쓰고 후반부 20%는 test용으로 쓴다.
3. average image section은 ceil(2432 * 0.8) 개의 train image에서 각 픽셀들의 평균값들을 계산하여 평균이미지를 계산한후에 train 이미지에서 평균값을 빼준다.
4. section은 eigenface들을 구하기 위하여 Eigen Value Decomposition(4-1)을 할 것인지 Singular Value Decomposition을 할 것인지 정하고 구한 Eigenvector를 Eigen Value 값이 큰 순서대로 왼쪽에서부터 다시 정렬한다. 이 코드의 SVD인 경우에는 정렬할 필요가 없다.
5. Eigenface를 출력하는 과정이며 Eigenface는 Eigen Vector의 하나의 열이 하나의 Eigenface가 된다.
6. Reconstruction section 에서는 각각의 input image에 따른 reconstruction을 보여주는 파트가 된다.

6번 section을 설명하자면 test image 중 하나를 랜덤하게 고르고 그 이미지(input)을 우리가 가진 vector(eigenface matrix)에 내적(projection)한다 [coeff = small_v' * (x_outlier - mean_x)]. 그러면 우리가 input으로 넣은 image가 vector들의 각 차원들에 얼마의 가중치를 가지고 있는지 알 수 있게된다 [coeff 를 알수 있게 된다]. 이렇게 알게된 가중치는 들어온 input 이미지를 설명하는 가중치가 되고 이를 vector(eigenface matrix)에 곱해줌으로써 이미지를 복원 할 수 있게된다.

'PCA, Sparse Coding' 카테고리의 다른 글

pca sparse coding #01  (0) 2017.01.17