본문 바로가기
유도항법제어/데이터기반제어

[POD-4] Gappy POD 매트랩 예제

by 세인트 워터멜론 2021. 3. 1.

Gappy POD 방법을 이용하여 손상된 얼굴 사진을 복구해 보자. 코드는 매트랩으로 작성했다.

 

 

(1) Extended Yale Face Database B에서 36명의 정면 얼굴 사진을 추출하여 스냅샷 행렬을 만든다. 데이터셋의 샘플 평균을 계산한다.

 

X = yaleFace(:, 1:36); % 32,256 by 36
mu = mean(X,2);

 

(2) 모든 데이터셋을 다음과 같이 치환한다.

 

\[ \mathbf{y}^{(i)} = \mathbf{x}^{(i) } - \mathbf{\mu} \]

 

(3) 데이터셋의 스냅샷 행렬을 만든다.

 

\[ Y = [ \mathbf{y}^{(1) } \ \mathbf{y}^{(2) } \ \cdots \ \mathbf{y}^{(m) } ] \ \in \mathbb{R}^{n \times m} \]

 

Y = X - mu;

 

(4) 스냅샷 행렬 \(Y\)의 특이값 분해(SVD, singular value decomposition)를 계산한다.

 

\[ Y=U \Sigma V^T \]

 

[U, S, V] = svd(Y, 'econ');

 

(5) \(d\)차원 (\(d \lt n\)) 직교 좌표축 \(\mathbf{w}_i, i=1, ..., d\) 를 선택한다.

 

\[ \begin{align} W &= [ \mathbf{w}_1 \ \mathbf{w}_2 \ \cdots \ \mathbf{w}_d ] \\ \\ &=[ \mathbf{u}_1 \ \mathbf{u}_2 \ \cdots \ \mathbf{u}_d ] = U_d \ \in \mathbb{R}^{n \times d} \end{align} \]

 

(6) 개피 데이터를 만들기 위해 임의로 얼굴 일부를 마스킹한다.

 

num_face = 33;
original_face = yaleFace(:, num_face); 

mask = ones(n*m, 1); 
mask(5000:30000,1)=0; 

marred_face = mask.*original_face;

 

원본 얼굴과 마스킹된 얼굴은 다음과 같다. 원본에서 \(77 \%\) 가량을 음영 처리한 것이다.

 

figure(1), axes('position',[0  0  1  1]), axis off
imagesc(reshape(original_face, n, m)), colormap gray

figure(2), axes('position',[0  0  1  1]), axis off
imagesc(reshape(marred_face, n, m)), colormap gray

 

 

 

(7) 마스크된 POD 모드 \(\tilde{\mathbf{w}}_j^i\) 를 구한다.

 

\[ \tilde{\mathbf{w}}_j^i = \mathbf{m}_i \otimes \mathbf{w}_j \]

 

d=36;
w_tilda = mask.*U(:, 1:d);

 

(8) Gappy POD의 모드 계수 \( \tilde{\mathbf{a}}_i \)를 계산한다.

 

\[ \tilde{\mathbf{a}}_i = \left( (\tilde{W}^i )^T \tilde{W}^i \right)^{-1} (\tilde{W}^i )^T \tilde{\mathbf{y}}^{(i)} \]

 

marred_test = marred_face - mu;

a_til = inv(w_tilda'*w_tilda)*w_tilda'*marred_test;

 

(9) 원래 데이터(얼굴)을 복원시킨다.

 

\[ \hat{\mathbf{x}}^{(i)} = \mathbf{\mu} + \sum_{j=1}^m \tilde{a}_{ij} \mathbf{w}_j \]

 

marred_face_til = mu + U(:,1:d)*a_til;

 

다음은 원본 얼굴과 원래 데이터로부터 복원된 얼굴, 그리고 개피 데이터로부터 복원된 얼굴이다. 실제와 구별할 수 없을 정도로 복원되었다.

 

origin_test = original_face - mu;
origin_face_til = mu + U(:,1:d)*U(:,1:d)'*origin_test;

figure(3), axes('position',[0  0  1  1]), axis off
imagesc(reshape(original_face,n,m)), colormap gray  

figure(4), axes('position',[0  0  1  1]), axis off
imagesc(reshape(marred_face_til,n,m)), colormap gray  

 

 

 

만약 개피 데이터를 일반 POD 알고리즘으로 처리하면 다음과 같이 얼굴 복원에 실패한다. 원본 얼굴과 비교해 보면 알 수 있다.

 

no_face_til = mu + U(:,1:d)*U(:,1:d)'*marred_test;

figure(5), axes('position',[0  0  1  1]), axis off
imagesc(reshape(no_face_til,n,m)), colormap gray  

 

 

 

참고로 원본 얼굴에 랜덤하게 93% 가량 마스킹을 한 개피 데이터에서도 얼굴을 잘 복원한다. 원본, 손상된 얼굴, 그리고 복원한 얼굴이다.

 

mask(randi(n*m, 30000, 1))=0;

 

 

 

Gappy POD는 제한된 수량의 센서를 사용한 유동 제어 문제에서 실시간으로 POD 모드 계수를 정확하게 추정할 수 있게 해주며, 또한 POD 모드 계수를 잘 추정하기 위해 센서의 배치 문제에도 적용할 수 있다.

센서의 배치 문제는 기본적으로 마스킹된 POD 모드 \(\tilde{\mathbf{w}}_j^i\)의 직교성을 유지하도록 센서의 위치를 선택하는 전략을 사용한다.

 

 

 

댓글