Ddanggle in Ml minutes

단 3줄로 힌튼의 드롭아웃 적용하기

이 글은 머신러닝 블로그 iamtrask 저자 Trask의 허락을 받아 단 3줄로 힌튼의 드롭아웃 적용하기의 듀토리얼 글을 번역한 것입니다. 원문도 꼭 읽어보셨으면 합니다.

단 3줄의 파이썬 코드를 바꾸고 힌튼의 네트워크 드롭 아웃을 설명 해 보겠습니다.

요약 : 드롭아웃은 뉴럴 네트워크 최근 기술 동향의 대부분에서 필수적인 부분입니다. 이 듀토리얼은 드롭아웃을 파이썬 코드 몇 줄로 설치하고 활용하는 방법을 알아봅니다. 이 글을 함께 다 읽고나면 드롭아웃 향상법이 어떻게 작동하는 지 이해하고, **응용하고 설치하면서 얻은 직관으로 앞으로 만나게 될 뉴럴네트워크에서 한 결 더 잘 활용할 수 있을 것 입니다. **

import numpy as np

X = np.array([[0,0,1], [0,1,1], [1,0,1], [1,1,1]])
y = np.array([[0,1,1,0]]).T

alpha,hidden_dim,dropout_percent,do_dropout = (0.5, 4, 0.2, True) # !!바뀐부분!!!
synapse_0 = 2*np.random.random((3, hidden_dim)) -1 
synapse_1 = 2*np.random.random((hidden_dim, 1)) -1 

for j in range(60000):
    layer_1 = (1/1+np.exp(-(np.dot(X, synapse_0))))
    if (do_dropout): # !!바뀐부분!!!
        layer_1 *= np.random.binomial([np.ones((len(X),hidden_dim))],1-dropout_percent)[0] * (1.0/(1-dropout_percent))
    layer_2 = (1/(1+np.exp(-(np.dot(layer_1, synapse_1)))))
    layer_2_delta = (layer_2 - y)*(layer_2*(1-layer_2))
    layer_1_delta = (layer_2_delta.dot(synapse_1.T) * layer_1*(1-layer_1))
    synapse_1 -= (alpha * layer_1.T.dot(layer_2_delta))
    synapse_0 -= (alpha * X.T.dot(layer_1_delta))

단계 1: 드롭아웃이란 무엇인가?

이전 글에서 살펴보았듯, 뉴럴 네트워크는 문제찾기를 있어보이게 만든 말입니다. 뉴럴 네트워크 안에 있는 각각의 노드들이 입력 데이터값과 결과 데이터값의 상관관계를 찾습니다.

뉴럴 네트워크

이전 글에서 살펴본 위에 있는 사진을 다시 봅시다. 선은 특정 웨이트의 모든 값들을 만들어내는 뉴럴 네트워크의 에러를 의미합니다. 선에서 (작은 에러로 불리는) 낮은 지점의 지점들은 그 선에서 입력 데이터값과 결과 데이터값의 상관 관계를 “찾은” 웨이트의 지점을 의미합니다. 그림에서 공들은 다양한 웨이트들을 의미합니다. 각각의 공들은 낮은 지점을 찾기 위해 계속 시도하죠.

색깔들을 주목 해보세요. (뉴럴네트워크의 웨이트와 비슷하게도) 공은 무작위적인 위치에서 시작합니다. 만약 두 공이 같은 색깔 영역에서 무작위 적으로 시작한다면 같은 지점에 수렴하게 됩니다. 하지만 무의미한 일입니다! 컴퓨터 계산과 메모리를 낭비합니다! 그렇지만 정확히 뉴럴네트워크에서 발생하는 일이기도 합니다.

왜 드롭아웃인가? 드롭아웃은 웨이트들이 같은 지점에 수렴하는 것을 막아줍니다. 한 방향으로만 전파하고 있을 떄는 가끔씩 노드들을 꺼버립니다. 그러고 나서는 역전파 할 때는 모든 노드를 다시 킵니다. 좀 더 자세히 살펴봅시다.

어떻게 드롭아웃을 설치하고 사용하나요?

드롭아웃을 설치하는 방법은 위 코드에서 ‘#!!!바뀐 부분’이 적혀 있는 곳이 잘 설명하고 있습니다. 레이어에서 드롭아웃을 수행하려면, (한 방향으로 전파하는) 전방향전파법에서 무작위적으로 어떤 레이어의 값들을 0으로 만들어주어야 합니다. 10번째 줄의 코드가 이 부분을 수행하는 코드입니다.

** 9번째 줄: ** 총체적인 드롭아웃에 선을 그어 놓습니다. 이미 봤듯이, 트레이닝을 하는 동안만, 드롭아웃을 사용해야 합니다. 실행되는 중에 사용하거나 테스트 데이터 집합으로 사용하지 않아야 합니다.

수정: 9번째 줄: 또 다른 방면으로는 전방향으로 전파하는 동안 값의 크기가 증가하도록 해줍니다. 간단하게 보면은, 만약 히든레이어 절반의 전원을 꺼버린다면, 결과값이 올바르게 나오도록 전방향으로 갈수있도록 푸시하는 값들을 두 배 늘려야합니다. 이 부분을 알려준 @karpathy에게 엄청난 감사인사를 전합니다.

최선의 방법으로 사용하기

4번째 줄: 어떤 노드 하나가 꺼질 확률에도 영향을 미치는 dropout_percent를 제한합니다. 이를 위한 좋은 초기 설정은 히든 레이어를 50%로 두는 것입니다. 만약 입력 레이어에 드롭아웃을 설치하고 싶다면, 25%를 넘지 않아야 합니다.

힌튼 교수는 히든 레이어의 크기를 조율하여 드롭아웃과 결합을 조율하는 것을 좋은 방법이라 말했습니다. 먼저 데이터에 완전히 적합해 질 때까지 드롭아웃의 전원을 끄며 히든레이어의 크기를 증가시킵니다. 그리고 나서, 히든 레이어 크기와 같게 드롭아웃의 전원을 키며 훈련시켜야 한다고 합니다. 이것이 거의 가장 좋은 설정입니다. 트레이닝이 끝나자마자 드롭아웃을 꺼버리면, 짜잔! 작동하는 뉴럴네트워크가 나옵니다!


댓글