for textmining

이탈리아 여행

|

지난 4일부터 1주일 간 로마를 시작으로 피렌체, 아시시, 베니스, 밀라노 5개 도시를 방문했다. 이 느낌을 오래 간직하기 위해 짧은 인상 위주로 정리해 둔다. (2018년 2월 11일 밀라노 말펜사 공항)

#01. 환승하기 위해 잠시 들렀던 터키 이스탄불 소재 아타튀르(Atatürk) 국제공항 서비스는 형편없었다. 환승 게이트 안내는 비행기 탑승 1시간 전에야 이뤄져서 환승객들이 공항 곳곳에서 갈팡질팡했다. 비행기 탑승 30분 전 게이트가 오픈된 것까지는 좋았다. 승객들을 게이트에서 스텝카(탑승용 계단차량)까지 실어나르는 버스에 가둬두고는 탑승시각이 넘어서까지 출발도 않고 대기하는 것 아닌가. 게이트를 관리하는 직원은 단 한 명. 항공편이 특별히 지연(delay)되어야 할 물리적 이유가 하나도 없었는데 이날 이스탄불발-로마행 TK1861편은 30여분 가까이 늑장 출발했다. 그에 반하면 인천공항은 정말이지 세계 최고 수준이다.

#02. TK1861편 창가에 비친 이탈리아의 첫 인상은 ‘따스한 햇살이 비치는 평온한 대평원’이었다. 날씨가 좋아서 로마 주변을 전체적으로 조망할 수 있었다. 드넓은 초지가 펼쳐져 있고 군데군데 조그마한 촌락들이 있으며 그 촌락들 사이를 거미줄처럼 잇는 길이 나 있었다. 자료를 찾아보니 테베레 강 유역, 아펜니노 산맥과 티레니아해 사이에 있는 넓은 평야지대를 ‘라티움(Latium)’이라고 한단다. 초기 고대 로마가 이곳을 중심으로 성장했다고 한다. 역시 그러면 그렇지. 라티움 같은 배후 생산지역이 없었다면 로마 같은 소비 도시는 탄생하기 어려웠을 것이다. 로마는 예나 지금이나 향락이 중심이다.

#03. 짐을 숙소에 내팽겨치다시피해서 처음 방문한 곳은 ‘콜로세움(Colosseum)’. 고대 로마 시대를 대표하는 원형 경기장이다. 테르미니역에 있는 숙소에서 멀지 않아서 우연히 Parco Del Colle Oppio 공원을 거쳐 가게 됐다. 그런데 공원에서 콜로세움을 후면에서 볼 수 있는 것 아닌가! 그것도 한적한 벤치까지 마련돼 있다. 지중해 따뜻한 겨울햇살을 내리쬐며 벤치에 앉아 한가로이 콜로세움을 바라보는 경험은 황홀함 그 자체였다. 이 글을 쓰는 지금도 그 때 그 감동을 잊을 수가 없다.

#04. 콜로세움을 기점으로 베네치아 광장(Piazza Venezia)에 이르는 거리 ‘Via dei Fori Imperiali’는 일요일이면 차없는 거리로 변신한다. 덕분에 온갖 행위예술인들이 세계 관광객들의 이목을 끈다. 특히 포룸 로마눔(Forum Romanum) 앞에서 공연하던 라틴 형제 3인방이 기억에 남는다. 기타 2, 콘트라베이스 1로 구성된 이들은 연주도 연주지만 한때 번성했지만 흔적만 남아있는 로마 중심 시가지를 배경으로 빼어난 실력을 뽐내고 있어 무척 아이러니하게 느껴졌다. 맥수지탄(麥秀之歎)이나 산 사람은 어찌됐든 살아야 한다. 3인방 중 한 명이 공짜로 주겠다며 CD 두 장을 내게 건넸다. 공짜인데 어찌 마다하겠는가. 그런데 노래 두 곡이 끝나고 나서 20유로를 달란다. 허허.. 주머니를 뒤집어 돈 없다는 시늉을 했다. 대신 노랫값만 내고 슬그머니 빠져나왔다. 역시 산 사람은 살아야 한다.

#05. 바티칸 시국 남동쪽에 있는 ‘성 베드로 대성당(Basilica di San Pietro)’과 바티칸 궁전 내 시스티나 성당(Aedicula Sixtina)은 이탈리아 여행 전체를 통틀어 최고라 할 만 하다. 규모도 웅장하고 장식과 그림 하나하나 정성이 깃들어 있다. 신자가 아니라도 절로 경외감이 들 정도로. 미켈란젤로가 시스티나 성당 벽에 그린 그림들이 압권이다. 1시간 넘게 ‘아담의 창조(천장)’, ‘최후의 심판(제단 쪽 벽면 전체)’을 구석구석 보느라 목 빠지는 줄 알았다. 당시 그들은 어떤 마음으로 프레스코화를 그렸을까. 그 신앙심이 존경스럽다.

#06. 로마에서 기차로 2시간여 거리인 소도시 아시시(Assisi). 평생 세속과는 멀리 하고 길거리에서 복음을 전파한 성 프란치스코(San Francesco, 1181-1226)가 이곳에 잠들어 있다. 프란치스코의 유해가 안치된 성 프란치스코 대성당 지하엔 성음악이 흐르고 있다. 거리는 적막할 정도로 조용하다. 그의 추종자들은 지금까지도 이 촌락에서 금욕적인 삶을 추구하며 수도 생활을 하고 있다. 그러나 상술 하나만큼은 철저히 세속적이다. 토마토와 치즈를 곁들인 피아디나(piadina)와 콜라 한 캔에 12유로(우리돈 1만7000원 가량)나 한다. 놀랍다.

#07. 피렌체에 있는 우피치 미술관(Galleria degli Uffizi)는 실로 대단하다. 그 빼어나고 방대한 작품들 모두 한 가문(메디치)이 기증한 것이라니. 미술에는 그다지 조예가 없어서 사람들이 많이들 감상하고 있는 작품들을 위주로 유심히 살펴보았다. 어떤 작품이든 자세히 들여다보면 그 디테일에 감탄하지 않을 수 없었다. 나중에 블로그 대문사진이나 휴대폰 잠금화면으로 쓰려고 그림 사진을 많이 찍어두었다.

#08. 비 갠 후 노을 진 피렌체 시내 겨울 풍광은 무척 아름답다. 피렌체 대성당의 쿠폴라(cupola)를 오르는 463개의 계단이 조금 버겁기는 하지만. 비가 주륵주륵 오는데도 기다린 보람이 있었다.

#09. 베니스엔 차가 없다. 바다와 운하를 오가는 곤돌라(gondola)들뿐이다. 경찰차, 구급차도 모두 곤돌라다. 버스도 물 위를 다닌다. 예전 베니스 귀족들은 곤돌라 치장에 꽤 많은 돈을 썼다 한다. 차 대신에 말이다. 어쨌든 저렴하고 탈 만한 지상 교통수단이 없어 베니스 시내 전체를 계속 걸어다닐 수밖에 없었다.

#10. 운좋게 베니스 2월 축제를 볼 수 있었다. 생각지도 못한 수확이었다. 춤과 노래는 언제나 흥겹다. 형형색색의 옷과 가면으로 치장한 사람들은 국적과 관계없이 거리에서 모두 친구가 됐다.

#11. 밀라노는 세계 패션 중심이다. 명품 상점들이 즐비하다. 행인들도 꽤 멋쟁이들인 것 같다. 하지만 밀라노는 화장실 인심이 박하다. 크디큰 쇼핑몰 안에 공용 화장실 하나 찾을 수가 없다. 가끔 찾는다 해도 0.5~1.5유로를 내야 한다. 그런데 저 수많은 사람들은 어디서 똥 누고 오줌을 싸는 걸까. 패션보다 중한 건 용변 해결일텐데. 용무가 급해서 공용 화장실을 찾느라 밀라노 중심가를 이리저리 뛰어다니다 든 생각이다.

Comment  Read more

밀라노의 상점들

|

지난 4일부터 1주일 간 이탈리아를 여행하고 있다. 마지막 행선지는 ‘세계 패션 중심’ 밀라노(Milano). 명성에 걸맞게 내로라할 만한 명품 브랜드 상점들이 거리에 즐비했다. 간판과 쇼윈도부터 행인들의 눈길을 확 끈다. 물건 그 자체보다는 감성과 경험을 내세운다. (내 입장에서)처음 보는 브랜드인데도 쇼윈도만 유심히 보면 이 가게가 뭘 팔고 뭘 내세울지 한 눈에 이해할 수 있었다. 책 한 권 팔더라도 고급지다(서점 Rizzoli). 브랜딩이니, 마케팅이니, 플랫폼이니 고민해야 하는 순간이 온다면 오늘 거닐었던 밀라노 거리 상점들을 잊지 말아야겠다. (2018년 2월 10일 밀라노)

Comment  Read more

Auto Regressive Models

|

이번 글에서는 Auto Regressive Model(AR)에 대해 살펴보도록 하겠습니다. 이 글은 전인수 서울대 박사과정이 2017년 12월에 진행한 패스트캠퍼스 강의와 위키피디아 등을 정리했음을 먼저 밝힙니다. 그럼 시작하겠습니다.

concept

자기 자신을 입력으로 하여 자기 자신을 예측하는 모형을 Auto Regressive Model(AR)이라고 합니다. 그 개념도와 likelihood 식은 다음과 같습니다.

저해상도 이미지/영상을 고해상도로 변환하는 작업을 Super Resolution(SR)이라고 합니다. SR을 AR modeling 관점에서 이해할 수 있습니다. 아래 그림처럼 고해상도 이미지/영상을 픽셀 단위로 예측하는 경우, $x_i$를 예측할 때는 이전의 모든 픽셀 예측 결과를 활용하게 됩니다.

앞으로 설명해드릴 PixelRNN과 PixelCNN은 SR을 AR modeling으로 해결해 보려는 시도들입니다.

PixelRNN

Recurrent Neural Network(RNN)는 시퀀스 데이터 처리에 특화된 아키텍처이므로 SR을 AR modeling으로 풀 때 적용해 봄직한 시도입니다. 아래 그림의 빨간색 픽셀을 예측할 때 이전의 모든 시퀀스 정보를 RNN 아키텍처에 넣어서 예측이 가능합니다.

PixelCNN

Convolutional Neural Network(CNN)는 본래 시퀀스 데이터 처리와는 직접 관련이 없으나 아래 그림처럼 Masked Convolution Filter를 사용하면 AR modeling이 가능합니다. 예측해야 하는 시점의 픽셀(아래 행렬의 정중앙 픽셀)과 아직 예측하지 않은 시점의 픽셀에 해당하는 필터 값을 0으로 설정해 두고, 이를 일반적인 conv layer에 적용하면 CNN을 가지고 AR modeling을 할 수 있습니다.

WaveNet

WaveNet은 음성 생성에 Masked Convolution Filter를 활용한 사례입니다. conv filter를 아래처럼 설정해 두면 현 시점 예측 때 과거 다양한 시점의 데이터를 사용하게 됩니다.

Comment  Read more

generative model 응용 사례

|

이번 글에서는 Generative model, 특히 Generative Adversarial Network(GAN)의 다양한 응용 연구들에 대해 살펴보도록 하겠습니다. 이 글은 전인수 서울대 박사과정이 2017년 12월에 진행한 패스트캠퍼스 강의와 위키피디아 등을 정리했음을 먼저 밝힙니다. PyTorch 코드는 이곳을 참고하였습니다. GAN과 관련해서는 이곳을 참고하시면 좋을 것 같습니다. 그럼 시작하겠습니다.

EnhanceNet

EnhanceNet은 GAN의 손실함수를 적용해 Super Resolution 기법의 성능을 높였습니다. Super Resolution(SR)이란 아래 그림처럼 저해상도의 이미지/영상을 고해상도로 변환하는 작업을 가리킵니다.

EnhanceNet이 SR 문제에 GAN 구조를 적용한 아이디어는 이렇습니다. 생성자 $G$의 인풋으로 노이즈 대신 저해상도의 이미지를 입력합니다. 판별자 $D$는 $G$가 생성한 가짜 고해상도 이미지와 실제 고해상도 이미지를 구분하는 역할을 합니다. $G$는 $D$를 속이도록 고해상도 이미지를 생성하도록 학습됩니다. 이처럼 EnhanceNet은 어떤 task이든 GAN 손실함수를 사용하여 원하는 결과를 얻어낼 수 있다는 점에서 눈길을 끕니다.

GAN 손실함수의 효과를 직관적으로 나타낸 그림은 아래와 같습니다. 원본 고해상도 이미지 $I_{HR}$에서 인위적으로 해상도를 낮춘 이미지 $I_{LR}$이 있다고 칩시다. $I_{LR}$을 인풋, $I_{HR}$을 정답으로 놓고 학습시킬 때 평균제곱오차(Mean Squared Error)를 손실함수로 많이들 씁니다. MSE는 아래 그림처럼 입력값과 정답을 평균(average)하려는 성향이 강하다(MSE와 관련해서는 이곳 참고)는 점이 단점입니다. 그런데 GAN 손실함수(adversarial loss)를 썼더니 $I_{HR}$을 제법 잘 근사하는 걸 확인했다고 합니다.

SimGAN

SimGAN의 목적은 현실감 있는 인공데이터를 만들어내는 데 있습니다. 이 때 GAN을 씁니다. 아이디어는 이렇습니다. 기존 GAN의 생성자 역할을 하는 Refiner $R$은 인공데이터를 받아서 실제 데이터로 변환하는 역할을 합니다. 판별자 $D$는 $R$이 생성한 가짜(refined) 데이터와 실제(real) 데이터를 구분하는 역할을 합니다. $R$이 $D$를 속이려고 하는 과정에서 $R$이 학습됩니다. 이 과정을 도식적으로 나타내면 다음 그림과 같습니다.

SimGAN에서는 다른 연구에 참고가 될 만한 몇 가지 기술들이 포함돼 있습니다. 우선 Self-Regularization입니다. $R$을 학습시킬 때 기존 GAN 손실함수만 사용할 경우, $R$이 그저 $D$를 속이는 데만 집중하게 되면서 $R$이 생성한 데이터가 실제 데이터와 완전히 동떨어지게 될 염려가 크기 때문입니다. $R$의 입력값인 인공데이터도 조악하나마 실제 데이터의 특징을 담고 있으므로 $R$의 손실함수에 다음과 같은 regularization 항을 추가했습니다.

위와 같은 항을 손실함수에 추가하게 되면 $R$에 입력되는 인공데이터 $x$와 $R$이 산출한 데이터 $R(x)$ 사이의 오차가 줄어들게 됩니다. 결과적으로 $R$이 생성하는 데이터가 입력데이터에서 너무 벗어나지 않게 되는 셈이죠. 단 여기에서 $ψ$는 입력값의 feature를 뽑는 함수인데요. 논문에서는 identity mapping을 사용했다고 합니다.

또 한가지 기법은 Local patch-Discriminator입니다. 기존 GAN에서 $D$는 입력데이터 전체를 보고 real/fake 여부를 판별합니다. 이 때문에 $G$는 대개 $D$를 속이기 위해 데이터의 일부 특징을 과장하려는 경향이 있습니다. 이 문제를 완화하기 위해 다음 그림과 같이 $D$가 데이터의 일부 영역만 보도록 하고, 전체적인 판단은 이들 패치의 평균이라든지 가중합이라든지 하는 방식으로 취하도록 했습니다. 그 결과 $D$의 능력을 어느 정도 제한하면서 $R$의 성능을 높일 수 있었다고 합니다.

마지막으로 언급할 부분은 History Buffer입니다. 기존 GAN에선 $D$를 학습시키는 과정에서 최근 학습샘플에만 적합하는 문제가 있었습니다. 이를 continual learning issue 내지 catastrophic forgetting problem이라고도 합니다. 이 문제를 해결하기 위해 도입된 것이 바로 History Buffer입니다. buffer에 예전 학습 데이터를 모아뒀다가 최신 데이터와 함께 학습시키자는 아이디어입니다. 결과적으로 $D$로 하여금 $R$이 예전에 생성한 데이터를 지속적으로 기억할 수 있게 도와줍니다. SimGAN에서는 아래와 같이 적용됐습니다.

  • 학습 도중 $R$이 생성한 데이터가 가운데 랜덤하게 반을 선택하여 buffer에 넣는다.
  • 각 step에서 buffer에서 랜덤하게 선택한 반과 $R$이 현재 생성한 데이터 반을 $D$에 전달한다.

Pix2Pix

Pix2Pix는 다음과 같이 image to image translation을 하는 데 GAN을 접목한 연구입니다.

아키텍처는 다음과 같습니다. 우선 $G$는 소스 도메인의 데이터를 입력 받아 타겟 도메인의 데이터를 생성합니다. $G$는 소스 도메인의 데이터와 생성된 타겟 도메인의 데이터를 쌍으로 묶어 $D$에 전달합니다. $D$는 $G$가 생성한 가짜 데이터 pair와 실제 데이터 pair를 구분합니다. $G$는 $D$를 속이도록 하는 과정에서 데이터를 더 잘 생성하게 됩니다.

$G$는 다음과 같이 오토인코더(autoencoder)에 Unet을 결합한 아키텍처를 썼다고 합니다. encoder, decoder 사이에 발생할 수 있는 정보손실을 skip-connection을 이용해 완화한 겁니다. Pix2Pix 역시 SimGAN의 Local Patch Disciriminator를 사용했다고 합니다.

CycleGAN

Pix2Pix의 단점은 학습데이터가 항상 pair로 존재해야 한다는 겁니다. CycleGAN은 이러한 문제를 해결하기 위해 제안됐습니다. 이를 도식적으로 나타낸 그림은 다음과 같습니다.

CycleGAN의 기본 프레임워크는 다음과 같습니다. 두 개의 생성자 $G$, $F$와 두 개의 판별자 $D_X$, $D_Y$를 씁니다. $G$는 $X$ 도메인의 데이터를 $Y$ 도메인으로 변환하는 역할을 합니다. $F$는 $Y$ 도메인의 데이터를 $X$ 도메인으로 변환합니다. $D_X$는 $F$가 생성한 가짜 데이터와 $X$ 도메인의 실제 데이터를 구분합니다. $D_Y$는 $G$가 생성한 가짜 데이터와 $Y$ 도메인의 실제 데이터를 구분합니다. $G$와 $F$는 반대 도메인의 구분자를 속이도록 적대적으로 학습됩니다. 이렇게 학습이 진행되면서 굳이 데이터가 pair 형태로 존재하지 않아도 됩니다.

CycleGAN에는 기존 GAN loss 이외에 cycle-consitency loss라는 것이 추가됐습니다. 아래 그림처럼 도메인을 변경했다가 다시 돌아왔을 때 모습이 원래 입력값과 비슷한 형태가 되도록 regularization을 걸어주는 것입니다. 이렇게 되면 도메인을 넘나들 때 더욱 현실감 있는 데이터가 생성될 것입니다.

CycleGAN을 PyTorch로 구현한 코드를 살펴보겠습니다. 우선 두 개의 $G$와 두 개의 $D$를 정의합니다. (일반적인 generator, discriminator 사용)

# Generator arguments : input_dim, num_filter, output_dim, num_resnet
G_A = Generator(3, params.ngf, 3, params.num_resnet) 
G_B = Generator(3, params.ngf, 3, params.num_resnet)
# Discriminator arguments : input_dim, num_filter, output_dim
D_A = Discriminator(3, params.ndf, 1) 
D_B = Discriminator(3, params.ndf, 1) 

$G$의 loss를 구하는 코드는 다음과 같습니다.

# A -> B
fake_B = G_A(real_A)
D_B_fake_decision = D_B(fake_B)
G_A_loss = MSE_loss(D_B_fake_decision, Variable(torch.ones(D_B_fake_decision.size())))

# forward cycle loss
recon_A = G_B(fake_B)
cycle_A_loss = L1_loss(recon_A, real_A) * params.lambdaA

# B -> A
fake_A = G_B(real_B)
D_A_fake_decision = D_A(fake_A)
G_B_loss = MSE_loss(D_A_fake_decision, Variable(torch.ones(D_A_fake_decision.size())))

# backward cycle loss
recon_B = G_A(fake_A)
cycle_B_loss = L1_loss(recon_B, real_B) * params.lambdaB

# Back propagation
G_loss = G_A_loss + G_B_loss + cycle_A_loss + cycle_B_loss

$D$의 loss를 구하는 코드는 다음과 같습니다.

# Train discriminator D_A
D_A_real_decision = D_A(real_A)
D_A_real_loss = MSE_loss(D_A_real_decision, Variable(torch.ones(D_A_real_decision.size())))
fake_A = fake_A_pool.query(fake_A)
D_A_fake_decision = D_A(fake_A)
D_A_fake_loss = MSE_loss(D_A_fake_decision, Variable(torch.zeros(D_A_fake_decision.size())))
D_A_loss = (D_A_real_loss + D_A_fake_loss) * 0.5

# Train discriminator D_B
D_B_real_decision = D_B(real_B)
D_B_real_loss = MSE_loss(D_B_real_decision, Variable(torch.ones(D_B_real_decision.size())))
fake_B = fake_B_pool.query(fake_B)
D_B_fake_decision = D_B(fake_B)
D_B_fake_loss = MSE_loss(D_B_fake_decision, Variable(torch.zeros(D_B_fake_decision.size())))
D_B_loss = (D_B_real_loss + D_B_fake_loss) * 0.5

StarGAN

StarGAN은 CycleGAN의 단점을 보완한 연구입니다. CycleGAN은 도메인 수가 늘어나게 되면 필요한 $G$의 수가 기하급수적으로 증가하고, $D$는 선형적으로 증가합니다. 아래 그림의 (a)의 경우 도메인 수가 4개가 되자, $G$는 12개, $D$는 4개가 필요한 것을 확인할 수 있습니다. 반면 StarGAN은 (b)와 같이 생겼습니다. $D$와 $G$는 각각 하나만 있으면 됩니다.

StarGAN의 학습 방식을 저자가 든 예시 기준으로 설명해 보겠습니다. CelebA 데이터셋과 RaFD 데이터 셋이 있고 각각의 레이블은 아래 그림과 같이 주황색, 녹색 박스라고 칩시다. Mask Vector는 모델이 현재 다루는 데이터가 CelebA에 속하는지, RaFD에 속하는지 나타내는 one-hot-vector입니다.

우선 (b)의 $G$에 입력되는 데이터를 보겠습니다. 이 데이터는 검은색 머리의 젊은 여성인데요, 타겟 도메인을 검은색 머리의 젊은 남자로 설정하였습니다. $G$의 입력데이터는 소스 도메인의 원래 이미지, 레이블 벡터, Mask Vector 셋을 합친 형태입니다. 어쨌든 $G$는 이 데이터를 검은색 머리의 젊은 남자로 변환해야 합니다. 이 데이터를 (d)의 $D$에 보내서 $D$가 실제 데이터로 구분하도록, 그리고 검은색 머리의 젊은 남자($[1,0,0,1,1]$)로 분류하도록 속여야 하니까요. $G$는 $D$를 잘 속일 수 있도록 학습됩니다.

(b)의 $G$가 생성한 데이터는 다시 $G$에 보내집니다. 이번에 $G$에 입력되는 데이터는 방금 전 $G$가 생성한 타겟 도메인의 이미지, 원 데이터의 레이블 벡터(검은색 머리의 젊은 여성, $[0,0,1,0,1]$), Mask Vector 셋을 합친 형태입니다. $G$는 이렇게 만든 데이터가 원래 이미지와 유사하도록 학습됩니다. 이는 CycleGAN의 cycle-consitency loss를 그대로 차용했습니다. 결과적으로 $G$는 하나의 이미지 데이터로 $D$를 속이는 과정에서, cycle-consitency loss를 줄이는 과정에서 두 번 학습되는 셈이죠. StarGAN의 목적함수는 다음과 같습니다.

Anormaly detection with GAN

GAN을 이상치 탐지, 즉 Novelty Detection에 활용한 연구도 있습니다. GAN은 $G$가 노이즈 $z$를 받아 현실감 있는 데이터를 생성하도록 학습되는데요. $G$가 생성한 데이터를 역추적해 latent space를 분석하면 이 latent space 내에서 특정 영역이 이상치에 해당할 것이라는 전제가 깔려 있습니다. 이를 도식적으로 나타낸 그림은 다음과 같습니다.

TripleGAN

TripleGAN은 GAN으로 새롭게 생성한 데이터를 활용해 성능이 좋은 분류기(classifier)를 만들어내는 게 목표입니다. 아키텍처와 목적함수를 도식화한 그림은 다음과 같습니다.

차근차근 살펴보겠습니다. 우선 생성자 $G$는 노이즈 $z$를 받아서 인공데이터 $x$를 산출하고 $y$는 실제 데이터로부터 샘플링합니다. $G$가 만든 데이터는 판별자 $D$와 분류기 $C$로 보내집니다. $D$는 이 데이터가 진짜인지 가짜인지 구분하며, $C$는 $G$가 만든 $x$를 입력으로 하고 역시 $G$가 만든 $y$를 출력으로 하는 classification task를 수행합니다.

레이블이 있는 실제 데이터($x_l, y_l$)는 분류기 $C$를 학습하는 데 사용됩니다(supervised learning). 이 데이터는 $D$에도 들어가 $D$가 진짜인지 가짜인지 구분하도록 학습됩니다. 마지막으로 레이블이 없는 실제 데이터($x_c$)가 분류기 $C$에 입력되면 $C$는 이 데이터의 레이블을 예측합니다. $C$가 잘 학습되어 있다면 $x_c$ 역시 레이블이 있는 데이터처럼 역할을 하게 되겠지요. 어쨌든 이렇게 레이블이 추가된 $x_c$ 역시 $D$에 입력돼 진짜/가짜 여부를 판별합니다.

TripleGAN에서는 $G$가 $D$를 속이는 과정에서 생성한 데이터가 $C$ 학습에 활용돼 $C$의 성능을 높일 수 있습니다. 뿐만 아니라 $C$는 레이블이 없는 데이터 $x_c$의 레이블을 예측할 때 $D$가 가짜라고 구분하지 않도록 그럴듯한 레이블을 달도록 학습이 진행됩니다. 결과적으로 TripleGAN의 학습이 잘 되면 기존 데이터만 가지고 학습한 것보다 성능이 좋은 분류기 $C$가 도출되리라고 기대할 수 있습니다.

Comment  Read more

Normalizing Flow

|

이번 글에서는 Normalizaing Flow(NF) 개념에 대해 살펴보도록 하겠습니다. 이 글은 전인수 서울대 박사과정이 2017년 12월에 진행한 패스트캠퍼스 강의와 위키피디아 등을 정리했음을 먼저 밝힙니다.

목적

변분추론(Variational Inference)의 목적은 계산이 어려운 사후확률 분포 $p(z$|$x)$를 계산이 쉬운 $q(z$|$x)$로 근사하는 것입니다. 우리는 evidence인 $p(x)$를 최대화하는 모델, 즉 데이터 $x$의 분포를 잘 설명하는 확률모형을 학습시키고자 합니다. 몇 가지 수식 정리 과정을 거치면 Evidence Lower Bound(ELBO)를 다음과 같이 도출할 수 있습니다. (수식 유도 과정에 대해서는 이곳 참고)

Variational AutoEncoder(VAE)에서는 근사 대상 확률함수 $q$를 다음과 같이 정의합니다.

VAE에서 사후확률분포 $q$를 위와 같이 정한 이유는 샘플링과 계산의 용이성 때문입니다. 그런데 이보다 더 복잡한 형태의 사후확률분포를 만들어낼 수는 없을까요? 예컨대 $q$에서 뽑은 잠재변수를 $z_0$라 둡시다. 그런데 VAE는 $q$를 단순한 가우시안 분포로 가정하기 하기 때문에 아래와 같이 $z_0$에 특정한 형태의 함수 $f_k$들을 반복 적용하여 모델이 더욱 복잡한 형태의 잠재변수를 표현하게끔 만들어주자는 것입니다.

이것이 바로 NF가 노리는 바입니다.

Change of Variables

$z’=f(z)$일 때 역함수가 존재하는 $f$와 임의의 확률분포 $q(z)$에 대해 다음 공식이 성립한다고 합니다.

따라서 $f$를 $K$번 적용한 $z_K$의 로그확률 $q_K(z_K)$값을 다음과 같이 표현할 수 있다고 합니다.

Normalizing Flow

그런데 이때 특정 함수 $f$를 사용하면 위 식의 행렬식(determinant) 부분을 쉽게 계산할 수 있다고 합니다. 그 종류는 다음과 같습니다.

$f$를 planar로 정했다고 칩시다. 이 경우 행렬식 부분은 다음과 같습니다.

$K$를 키울 수록 잠재변수를 더 복잡하게 모델링할 수 있습니다. 예컨대 다음과 같습니다.

Comment  Read more