유도항법제어/데이터기반제어

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

깊은대학 2021. 3. 1. 16:39

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\)의 직교성을 유지하도록 센서의 위치를 선택하는 전략을 사용한다.