GTX 960: 초당 60 sample 학습

GTX 1080: 초당 140 sample 학습



돈이 최고군..

'뻘글' 카테고리의 다른 글

TensorFlow를 배우자  (0) 2016.05.13
구글은 정말 짱인 것 같다  (0) 2016.05.10
블로그를 만들었다  (0) 2016.05.09

Theano에 점점 익숙해지고 있다.

느긋한 컴파일 시간과 이해하기 힘든 에러 메시지가 늘 당황스럽긴 하지만, 1) 컴파일 시간엔 화장실이라도 다녀 오는 여유를 가지고 2) 에러 메시지를 해석하기 힘들다면 빨리 포기하고 REPL 환경에서 한 줄씩 실행하며 에러를 재현해 보는 태도를 가지면 할 만하다.


하지만 아직은 너무나 Theano도 딥러닝도 초보인지라 어이 없는 코드를 짜는 경우가 많다. 이 포스팅은 나 같은 사람을 위한 것이다.


1. reshape를 적극 활용하자 / scan의 사용을 피하자

numpy에서도 그랬듯, reshape는 데이터 자체는 그대로 둔 채 단지 "모양"만 바꾸는 작업이다. dimshuffle(TensorFlow에서는 transpose)보다 훨씬 더 빠른 연산. map이나 scan을 쓰고 싶은 욕구가 드는 데이터(예를 들어 batch로 처리할 때!)가 있다면, reshape를 이용해 낮은 dimension으로 낮춘 후 map이나 scan을 쓰지 않는 방향으로 하는 편이 좋다.

좋은 예로는 batch로 RNN을 이용한 sequence prediction을 학습하는 과정에서 categorical cross entropy loss를 계산하는 상황이 있겠다.

batch로 처리하므로, cross entropy를 계산하기 위해서는 batch 크기 B, 길이 T, hidden dimension H, output dimension C라고 할 때 B x T x H 크기인 hidden state들에 대해 H x C 크기의 매트릭스를 곱해 B x T x C 크기의 logit을 얻고, 각 logit에 softmax를 적용한 후 cross entropy 수식에 넣어야 한다.

이 때, softmax 함수의 분모는 3번째 dimension의 값들끼리만 의존 관계가 있고, 앞의 두 dimension과는 상관이 없으므로 logit을 (B * T) x C 크기의 2차원 매트릭스로 펼친 후 theano.tensor.nnet.softmax 및 categorical cross entropy 함수를 적용하면 된다.

단순히 loss를 계산하고자 하는 거라면 다시 reshape를 통해 원래의 B x T x C 크기로 바꿔 줄 필요 없이 바로 평균을 사용하면 됨!

이걸 생각 못하고 map을 이용해서 batch마다 softmax를 계산하고 cross entropy를 계산하고 더한 후 batch 크기로 나눠서 짰더니 훨씬 느렸다... (2배 이상!)


또한, reshape가 적용되지 않는 경우라 해도 메모리가 허락하는 선에서 scan의 사용은 되도록 피하는 것이 좋겠다. map 함수가 있긴 하지만, scan을 이용해 구현했기 때문에 parallel하게 빠르게 연산이 수행되지도 않는다. temporal한 의존성이 없다면 broadcasting을 활용해 메모리를 팍팍 쓰면서 큼직큼직하게 처리하는 것이 좋다.


2. 작은 매트릭스 곱을 여러 개 하는 것보다, 큰 매트릭스 곱을 조금만 하자

특히 LSTM에서 1.5배 가량의 성능 향상을 본 경우인데, 단순히 LSTM 수식을 그대로 구현하면 작은 매트릭스가 매우 많이 나온다.

이걸 하나씩 일일이 곱하기보다는, 큰 매트릭스 하나를 만들어서 최대한 곱셈의 수를 줄이는 것이 좋다.

좀 더 자세히 설명하자면 다음과 같다. (input dimension D, hidden dimension H라 가정)

식에서는 총 input에 곱하는 4개의 matrix (D x H), hidden state에 곱하는 4개의 matrix (H x H), cell에 곱하는 3개의 matrix (H x H), 4개의 bias (H x 1)가 등장한다.

이를 따로 처리하려면 상당히 많은 매트릭스 곱이 필요하다.

이 때, 앞의 8개의 matrix를 크기 (D + H) x 4H인 1개의 matrix 곱으로 만들고, 앞에 input과 hidden state를 합친 크기 (D * H) x 1인 벡터를 곱하면 연산을 상당히 줄일 수 있다. 또, cell에 곱하는 3개의 matrix는 peephole connection을 의미하는 diagonal matrix이므로, matrix 형태로 사용하기보다는 크기 (H x 1)인 벡터의 element-wise 곱으로 바꿔 계산할 수 있다.

Theano는 미리 구현해둔 함수들이 많지 않아 직접 구현하느라 비효율적으로 짰지만, 대부분의 딥러닝 라이브러리에서 위와 같은 식으로 구현하고 있다. (Tensorflow, Chainer 등.)

'약간 유익한 글' 카테고리의 다른 글

Linux Mint 17.3 Cinnamon 설치 후 몇 가지 설정들  (1) 2016.06.22
결국 Theano  (1) 2016.06.20
조금 더 TensorFlow  (0) 2016.06.05
TensorFlow와 Chainer 비교  (0) 2016.05.27
loss 값은 accuracy가 아니다  (0) 2016.05.16

몇 가지 이유로 며칠 전부터 리눅스 민트를 쓰고 있다.

곧 정식 18 버전이 나온다는데, 난 우분투도 14.04를 계속 쓰고 있었기에 17.3을 설치했다.

일단 깔끔해서 좋고, 시작 표시줄 비슷한 게 있어서 좋다!

mate랑 cinnamon 중에 고민했었는데, 더 이쁜 거 같아서 cinnamon을 골랐는데... system tray 관련해서 약간의 고생을 하게 되었다 ^^;


1. Dropbox system tray 아이콘 문제

드롭박스를 그냥 설치하면 트레이에 있는 아이콘이 먹통이 된다!

이것뿐이면 괜찮은데, 가끔 아예 아이콘이 사라지는 문제도 발생.

이건 dbus-launch를 이용해 드롭박스를 실행하면 해결된다.

부팅 시 자동 실행을 위해서는 다음과 같이 수정.

- ~/.config/autostart/dropbox.desktop을 복사해 둔다.

- 드롭박스 설정에서 "시스템 시작 시 자동 시작" 같은 옵션을 해제. (dropbox autostart n 명령으로 할 수도 있는데, 나는 자꾸 재부팅하면 자동 시작 옵션이 다시 켜지더라)

- 복사해 둔 dropbox.desktop 파일에서 Exec=dropbox start -i 라인을 Exec=dbus-launch dropbox start -i로 수정

- ~/.config/autostart/ 디렉토리 내에 수정한 파일을 집어넣는다.


2. Input method 문제

우분투에서는 nimf를 잘 쓰고 있었는데, 리눅스 민트에서는 uim-byeoru를 가장 많이 쓴다고 하길래 uim-byeoru를 설치했다.

그런데 위의 드롭박스 문제와 비슷하게 system tray 아이콘이 먹통이 되는 현상이 발생. (이거 쓰면서 생각해 보니 dbus-launch로 실행시키면 해결될 수도...? 그런데 autostart 커맨드가 어디 있는지 못 찾긴 했음.)

그래서 우분투 16.04부터는 기본 입력기가 된 fcitx를 사용하기로 했다.

input method에서 그냥 fcitx를 고르면 한글 입력 시 문제가 있다. (한글 쓰다가 한/영 키 눌러서 바꾸면 마지막 글자 사라짐)

그래서 floor라는 분의 ppa에 있는 fcitx를 이용하기로 결정! (ppa:createsc)

리눅스 민트 17.3은 우분투 14.04를 베이스로 하므로 구버전을 담아 두는 copy4를 이용하면 된다.

- sudo add-apt-repository ppa:createsc/copy4

- sudo apt-get update

- sudo apt-get instal fcitx fcitx-hangul

잘 된다! 가장 만족스러움.

혹시 트레이 메뉴에 중국어로 된 메뉴가 뜬다면 startup applications에서 fcitx와 관련돼 보이는 걸 체크 해제하면 됨.

'약간 유익한 글' 카테고리의 다른 글

Theano 및 LSTM 속도 향상 방안  (0) 2016.06.25
결국 Theano  (1) 2016.06.20
조금 더 TensorFlow  (0) 2016.06.05
TensorFlow와 Chainer 비교  (0) 2016.05.27
loss 값은 accuracy가 아니다  (0) 2016.05.16

+ Recent posts