2017년 2월 28일 화요일

초짜 대학원생의 입장에서 이해하는 Unrolled Generative Adversarial Networks (2)

* Unrolled Generative Adversarial Networks - L. Metz et al. 2016을 바탕으로 작성한 리뷰

이전 글의 마지막 부분에서 unrolled GAN이 어떻게 기존의 GAN과 다른지 짧게 살펴보았었습니다. 오늘은 그 부분에 대해 좀 더 설명을 하고 unrolling한 결과가 어떤 지에 대해 확인해보겠습니다.




2017년 2월 19일 일요일

초짜 대학원생의 입장에서 이해하는 Unrolled Generative Adversarial Networks (1)

* Unrolled Generative Adversarial Networks - L. Metz et al. 2016을 바탕으로 작성한 리뷰


Unrolled GAN이 풀고자 하는 문제


오늘 소개할 논문에서 풀고자 하는 문제는 GAN의 고질적 문제 중 하나인 불안정한 학습의 안정화(stabilize)입니다. GAN의 불안정성은 크게 세 가지 문제로 정리되는데요:

GAN의 불안정성


  1. Mode collapsing or dropping (generator)
  2. Generator and discriminator oscillating during training
  3. No learning when the power between generator and discriminator is unbalanced.

세 가지 문제가 사실 다 연결되어 있습니다. 게다가 Kullback Leibler (KL)와 같이 mode-covering divergence를 사용하는 경우에도 생성 모델이 수렴하고 나서도 전체 분포를 포괄(cover)하지 못하는 경우가 있습니다.

말로만 불안정하다라고 얘기하는 것보다 예시를 보는게 감이 팍 오지요. 아래 그림은 그 중 mode collapsing이라는 문제를 보여줍니다.

Unrolled GAN(위) vs. standard GAN(아래)

가장 오른쪽 열에 target이 우리가 찾고자 하는 data distribution이라고 생각하시면 됩니다. 2D Gaussian 분포들을 여러 개 섞은 형태의 dataset이네요. 왼쪽에서 오른쪽으로 갈 수록 학습이 진행되는 것이고(step 0 ~step 25k) 각각의 step에서 보여주는 그림은 해당 step에서 학습한 generator distribution이라고 생각하시면 됩니다.

위 줄의 unrolled GAN은 점차 여러 mode를 가진 분포를 찾아가는 반면 아래 줄의 standard GAN은 각각의 mode들을 번갈아 돌아가면서 전체적인 데이터 분포를 찾지 못하고 한 번에 하나의 mode에만 weight를 주는 것을 보실 수 있습니다. 즉, mode collapsing이 일어나는 것이죠.

좀 더 구체적인 예시로 이해를 해보겠습니다.

MNIST 데이터로 학습한 결과 비교

여전히 위 줄이 unrolled GAN이고 아래 줄이 standard GAN 결과입니다. 아래 줄은 학습이 잘 안 되기도 했지만(숫자가 아니라 뭔가 이상한 패턴이죠..), 학습이 진행될 때 각 step마다 다른 single mode의 sample 즉, 한 가지 문양만 종류를 바꿔가며 보여줍니다. 이에 반해서 위 줄의 unrolled GAN은 언제나 대부분의 숫자들을 골고루 다 생성하여 보여주는 것을 확인하실 수 있습니다.




2017년 2월 14일 화요일

초짜 대학원생의 입장에서 이해하는 Deep Convolutional Generative Adversarial Network (DCGAN) (2)

Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks - Alec Redford et al. (2016)을 기본으로 작성한 리뷰. 

이전 글에 이어 빠르게 DCGAN 결과와 분석 내용을 다뤄보도록 하겠습니다. 먼저 저번 글에서 이번에 소개할 내용과 관련된 부분을 한번 더 짚고 넘어가겠습니다.

빠른 복습


생성 모델들에 대한 연구에서 꼭 보여줘야할 내용은 다음과 같습니다:

  1. Generator가 이미지를 외워서 보여주는 것이 아니란 것을 확인시켜줘야합니다. (즉, memorization이 일어난 것이 아니란 것을 보여줘야 합니다.) 
  2. Generator의 input 공간인 latent space ($z$ space)에서 움직일 때 급작스러운 변화(sharp transition)이 일어나는 것이 아닌 부드러운 변화를 보여줘야합니다. (이를 논문에서는 "walking in the latent space"라고 표현하는데요 재미있는 표현인 것 같습니다.)

1과 2는 사실 같은 맥락에서 이해할 수 있다고 말씀드렸었죠. Memorization이 일어난다는 말은 Generator가 유의미한 특정을 학습하는 것이 아니라 overfitting이 일어나서 1:1 matching을 하는 mapping을 배웠다는 얘기입니다. 따라서 굳이 latent space에서 어떤 부드러운 변화가 있을 이유가 없습니다(바로 옆의 $z$값이 다른 sample과 1:1 연동이 될 수 있다는 말입니다.).




2017년 2월 13일 월요일

초짜 대학원생의 입장에서 이해하는 Deep Convolutional Generative Adversarial Network (DCGAN) (1)

* Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks - Alec Redford et al. (2016)을 기본으로 작성한 리뷰. 

오늘 다룰 논문에서 보여줄 내용에서 제가 아주 재미있다고 생각한 부분을 먼저 소개해드리면서 시작해보겠습니다.
$$KING~(왕) - MAN~(남자) + WOMAN~(여자)$$
만약 위에 수식을 계산해야한다면 어떤 단어가 답이 될 것이라 생각되시나요?
$$QUEEN~(여왕)$$
은 어떤가요? 사람에게는 이런 연산이 그리 어려운 일이 아니지만 컴퓨터에게 이런 연산은 사실 1) 단어의 의미를 이해하고 2) 그에 맞는 새로운 단어를 찾는 생각보다 고차원의 처리가 필요한 어려운 문제일 수 있습니다. 이런 문제를 인공신경망으로 해결하려 한 것이 word2vec이란 이름으로 연구되어있고 이 또한 상당히 흥미로운 주제 중 하나입니다.

오늘 소개해드릴 DCGAN은 이런 문제를 단어나 말뭉치가 아닌 이미지에서 하는 것이 가능하다는 것을 보여줍니다. 예를 들자면 실제 논문에 있는 그림인데 다음과 같은 것을 말합니다:


지금 여기에 나온 사진들은 실제 사진 등으로 찍은 이미지가 아닌 모두 다 학습된 뉴럴 네트워크가 만들어낸 이미지입니다.

이 이미지를 만들어내는 입력값($z$) 중에 "안경을 쓰고 있는 남자들"을 그리게 하는 입력값들을 모아 평균치를 구하고, "안경 없는 남자""안경 없는 여자"들을 만들어 내는 입력값들에 대해서도 평균치를 구한 후 각각 빼고 더해주면 새로운 입력값($\tilde{z}$)들이 나오겠지요?

그 입력값들($\tilde{z}$)을 다시 뉴럴 네트워크에 넣어서 이미지가 뭐가 나오는지 보면 놀랍게도 "안경을 쓴 여자"가 나온다는 것입니다. 심지어 이 결과들이 처음부터 이런 문제를 풀기 위한 것이 아니라 이미지를 생성하기 위해 학습을 하고나서 부수적으로 얻은 결과라는 것이 매우 놀랍죠....

아무튼 여러분이 DCGAN에 흥미를 가지셨다면 성공입니다. 이젠 DCGAN이 어떻게 이런 결과가 나오도록 학습한 것인가?!에 대해 찬찬히 살펴보겠습니다.




2017년 2월 8일 수요일

Docker나 가상머신 없이 Window에서 TensorFlow 설치하기: TensorFlow를 Python IDE에서 사용하기

앞선 글을 따라서 TensorFlow도 잘 깔았고, 이제 본격적으로 코딩을 해보고 싶은데 돌아가는지 확인했듯이 명령창에서 python을 실행하여 코딩을 할 수도 없는 노릇이고...원래 코딩을 하듯이 jupyter notebook에서 코드를 실행하거나 pycharm과 같은 IDE에서 돌리고 싶은데 어떻게 해야하는가?.....를 오늘 알아보겠습니다. 일단 저는 IDE를 새로 깔지는 않은 관계로 Anaconda를 깔면 같이 딸려오는 spyder를 사용하겠습니다.

Anaconda 가상환경에서 IDE 실행하기 

명령창에 activate (가상환경이름) 을 실행하여 가상환경으로 들어가고 난 후, 원래 IDE를 실행하던대로 더블클릭해서 spyder를 켰는데 import tensorflow as tf 라고 한 것을 전혀 인식하지 못하고 import error가 뜰 것입니다. 

아니 뭐지?!

..라 하시겠지만 당연한 결과입니다. 가상환경 "위에서spyder를 실행해주지 않았기 때문에 그런 문제가 생기는데요 사실 Anaconda에서 가상환경으로 따로 설정을 해주지 않고 global에 바로 TensorFlow를 설치했다면 위와 같이 IDE를 실행하셨더라도 별다른 오류가 나지 않았을 것입니다. 이미 global(default 환경)에 TensorFlow가 깔려있기 때문이죠.

즉, 가상환경에 들어가신 후, 명령창에서 spyder 라고 실행시켜서 들어가시면 아무 문제 없이 TensorFlow가 import되는 것을 보실 수 있습니다. 혹은 자주 이렇게 실행하다보면 Window 검색에 뜨더군요. 아래 그림과 같이 spyder의 경우는 가상환경 path preference가 고정된 채로 바로 클릭하여 실행하실 수도 있습니다.


그러면 귀찮게 왜 굳이 virtualenv를 만들어서 설치를 하는지에 대해 의문이 들 수 있겠죠. 뭐 추가로 윈도우에서 Python을 이용한 다른 응용을 개발하지 않고 기존 시스템과의 충돌이 걱정되지 않는다면 global에 설치하셔도 아무 문제 없습니다. 

다만, 가상환경을 만들면 기존 시스템과의 충돌을 막을 수 있고 (Python version 등) 가상환경을 지워주기만 하면 깔끔하게 모든 dependency가 삭제되므로 가상환경 위에서 설치하는 것을 권장하는 것으로 보입니다. 

아 참고로 가상환경 삭제는 다음과 같이 하시면 됩니다. 
conda remove tensorflow35

* Pycharm의 경우는 시험해보지 않았습니다만 명령창에서 spyder와 비슷하게 실행하거나 따로 Pycharm을 실행하신 후 가상환경 path 설정을 preference에서 해주면 될 것입니다.
** 구글 검색으로 나온 관련있어 보이는 링크를 하나 첨부하겠습니다. (PyCharm:: virtualenv+pythonz 환경 추가하기)

Anaconda 가상환경에서 jupyter notebook 실행하기

같은 원리로 jupyter notebook도 가상환경 위에서 실행해주시면 아무 문제 없이 import가 되는 것을 보실 수 있습니다. 
(tensorflow35) C:\Users\Jaejun Yoo> jupyter notebook

Trouble shooting

간혹 IDE나 Jupyter notebook에서 다음과 같은 에러가 뜰 경우가 있는데요....
InternalError: Blas SGEMM launch failed : a.shape=(3, 3), b.shape=(3, 1), m=3, n=1, k=3 [[Node: MatMul_3 = MatMul[T=DT_FLOAT, transpose_a=false, transpose_b=false, _device="/job:localhost/replica:0/task:0/gpu:0"](_recv_Placeholder_2_0/_1, Variable_3/read)]]



지금까지 제가 겪어본 바를 바탕으로 말씀드리자면 짐작되는 이유가 세 가지 있습니다.
  1. Jupyter notebook과 IDE가 동시에 켜져있을 경우 
  2. kernel restart가 필요한 경우
  3. tf.one_hot(~) 함수를 사용하고 있는 경우

sol1) 첫 번째 경우라면 둘 중 하나를 끄고 사용하셔야합니다. Kernel이 뭔가 충돌을 일으키는 것으로 보입니다.

sol2) 첫 번째 경우가 아닐 경우 다음으로 시도해볼 수 있는 것이 두 번째와 같이 kernel restart를 해보는 것입니다. IDE와 달리 Jupyter notebook에서는 쉽게 restart가 가능하지만 가장 확실한 것은 아예 IDE 혹은 Jupyter notebook을 종료하고 재시작 해보는 것입니다.

* 이 sol3의 경우 tf 1.0.0.rc2에서 버그가 해결되었습니다.!!
sol3) 마지막으로 tf.one_hot() 함수를 사용하고 있을 경우 입니다. 무슨 이유인지는 정확히 모르겠으나 TensorFlow 1.0.0.rc1(2017.02.04 버전)까지 수정 안 되어있는 버그인 것으로 보입니다. gpu 버전의 tensorflow에서 address가 충돌을 일으키거나 assign이 잘 안되는 것 같은데 자세히 살펴보지는 않았습니다. tensorflow github의 issue로도 등록되어있는 문제인데 일단 우회하는 방법들이 몇 추천되어있습니다. 제가 이 것을 몰라서 매우 삽질을 하였는데....orz....스스로 발견한 one_hot encoder function을 안 쓰고 우회하는 방법을 세 가지 정도 정리해보았으니 필요하시면 제 github의 three ways to avoid tf.one_hot function repository를 찾아주시면 됩니다.

error 관련 참고 링크



2017년 2월 2일 목요일

자신의 blogger/blogspot에서 HTML DIV tag를 이용하여 글에 스크롤바 넣기와 제어하기

코드를 적을 때 간혹 한 줄이 너무 길어 블로그 창에서 넘어가는 경우가 있다. 그 때는 다음과 같이 html div tag에 overflow를 사용하여 scroll을 넣게 해줄 수 있다.
<div style="overflow:scroll;>
</div>

다만 이 경우, overflow가 있는 것과는 관계 없이 항상 스크롤이 들어가므로,
<div style="overflow:auto;>
</div>
이와 같이 auto로 바꾸면 overflow가 있을 때만 스크롤이 생기게도 할 수 있다.



Docker나 가상머신 없이 Window에서 TensorFlow 설치하기: tensorflow-gpu + Window (7,10) 설치 가이드입니다.

Tensorflow Window 버전이 드디어 나왔습니다! (물론 이미 작년 얘기이지만...거의 나오자 마자 깔았으므로 ㅎㅎ) 2016년 11월 29일에 tensorflow 0.12.0-rc0 버전이 릴리즈되면서 Ubuntu에서만 가능하던 GPU 버전이 설치가 가능해졌습니다. 그 이후에 벌써 update가 여러번 진행되어서 현재 (2017.2.10일) 기준 1.00.rc2 버전이 나와있습니다. 그럼 간단히 설치방법부터 동작 확인하는 것까지 정리해보겠습니다.

그림 1 TensorFlow Window버전 출시 관련 release note



설치방법

Prerequisites

  1. CUDA 8.0.44 -win 10 설치
  2. CuDNN 5.1 설치
본격적으로 TensorFlow를 설치하기 전에 먼저 설치를 해줘야할 패키지들이 있습니다. 그림 1 TensorFlow Window버전 출시 관련 release note에서도 보실 수 있듯이 Tensorflow 0.12.0 RC0 버전부터는 GPU acceleration을 위해 CUDA 8.0과 cuDNN 5.1(NVIDIA에서 제공하는 Deep learning을 위한 추가 라이브러리 package)을 권장하고 있습니다. 
CUDA 8.0은 Network 버전보다 local 버전으로 1.2기가 정도의 파일을 직접 받아 설치하는 것이 훨씬 빠릅니다.
링크: https://developer.nvidia.com/cuda-downloads
CuDNN은 NVIDIA에서 회원가입을 하고 다운을 받으시면 됩니다. 다운받고 나면 그냥 압축 파일인데 이를 풀어서 CUDA 설치 경로에 붙여넣어 덮어씌워주시면 됩니다.
링크: https://developer.nvidia.com/cudnn
CUDA 설치경로: C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0

Anaconda Installation

위의 패키지들을 모두 설치하였다면 본격적으로 TensorFlow를 설치할 준비가 된 것입니다. Anaconda를 이용하여 설치를 진행하도록하겠습니다. Anaconda는 Python distribution으로 여러 유용한 패키지들을 포함하고 있습니다. 가상환경을 만들 수도 있는데 이를 통해 Python 버전 간의 충돌을 막을 수도 있고 매우 편리합니다. Python이 아직 깔려있지 않은 분도 Anaconda를 깔면 자동으로 path 정리 등이 되므로 그냥 Anaconda를 깔아서 사용합시다.

사실 Tensorflow.org에서 설치 가이드를 확인하시면 Anaconda installation이란 part가 있고 앞부분은 이를 따라하시기만하면 됩니다만...이 글은 무작정 따라하기 방식으로 포스팅하기로 했으므로 한글로 다시 정리해드리겠습니다.
먼저 크게 다음과 같은 흐름으로 설치가 진행됩니다.

  1. Anaconda 설치
  2. Conda 가상환경 설정
  3. 가상환경을 activate하고 TensorFlow를 설치
  4. 앞으로 TensorFlow 실행하기 전에 가상환경을 먼저 activate
  5. 가상환경에 ipython(jupyter notebook) 등의 부가적 package 설치

1번부터 차근차근 해보겠습니다. Anaconda에도 Python 버전에 따라 두 가지 버전이 있는데 일단 설치링크를 따라가서 Python 3.5 버전을 설치합니다.
* 아직까지는 TensorFlow가 Window에서는 Python 3.5만 지원하기 때문에 Anaconda가 업그레이드 된 경우 아카이브로 들어가셔서 Anaconda3-4.2.0-Windows-x86_64 버전을 받아 깔아주시면 됩니다 (20170206 기준 Anaconda가 Python 3.6으로 업그레이드 되었네요).

2번의 가상환경이 무엇인지는 cs231n 수업 환경설정에 관한 글 중간(3번)에 설명이 되어있습니다.  저는 TensorFlow Python 3.5 버전을 설치를 할 것이기 때문에 tensorflow35라는 이름으로 가상환경을 만들어주었습니다.
conda create -n tensorflow35 python=3.5 anaconda

앞으로는 tensorflow를 사용할 때마다 cmd 창을 열어서
activate tensorflow35
deactivate tensorflow35
라고 명령어를 실행해주시면 가상환경에 접속(activate)하거나 나올 수(deactivate) 있습니다.

그럼 이제 이 가상환경을 활성화한 후 이 위에 TensorFlow-GPU 버전을 설치해보겠습니다. conda를 이용하면 이 역시도 매우 편하게 설치가 가능합니다.
conda install tensorflow-gpu
*현재 Anaconda version이 업그레이드 되면서 conda로 install할 경우 package가 없다는 오류가 뜨는 경우가 발생하는 것 같습니다. 그런 경우 pip을 사용하여 깔아줍시다.
pip install tensorflow-gpu
이후에 새로운 버전이 나오면 업데이트해주는 것 역시도 매우 간단합니다. (아래 예시는 2017.02.10 기준 가장 최신인 1.0.0.rc2 업데이트입니다.)
pip install --ignore-installed --upgrade https://storage.googleapis.com/tensorflow/windows/gpu/tensorflow_gpu-1.0.0rc2-cp35-cp35m-win_amd64.whl

현재 자신의 TensorFlow 버전을 알고 싶다면 TensorFlow를 설치해준 가상환경으로 들어가서
pip freeze
라고 하면 설치된 프로그램들의 버전이 모두 나옵니다. 이 방법 외에도 cmd에서 python을 실행한 후 import tensorflow as tf; print(tf.__version__)이라고 실행하면 자신의 현재 버전을 바로 알 수 있습니다.

설치 확인

이제 설치가 완료되었으면, TensorFlow가 잘 동작하는지 확인할 필요가 있겠죠? cmd창에서 python을 실행시킨 후에,
python
아래와 같이 script를 실행해 봅니다. 정상적으로 설치가 완료되었다면 다음과 같이 결과가 나올 것입니다.

>>> import tensorflow as tf
>>> hello = tf.constant('Hello, TensorFlow!')
>>> sess = tf.Session()
>>> print(sess.run(hello))
b'Hello, TensorFlow!'
>>> a = tf.constant(10)
>>> b = tf.constant(32)
>>> print(sess.run(a + b))
42

* (string 앞에 b가 찍히는 이유) Hello, TensorFlow 앞에 'b'가 붙는 것은 는 python 버전 때문인 것 같습니다. 리눅스 python 2.x 버전에서는 그렇지 않다고 하네요.

이로써 TensorFlow GPU 버전 윈도우 설치가 완료되었습니다. 모두 즐거운 코딩되시길 ㅎㅎ 다음 번에는 jupyter notebook과 window IDE에서 python code를 돌리는 것에 대해 글을 작성해보겠습니다.

다음 읽을거리