본문 바로가기
프로그래밍 놀이터/머신러닝, AI, 딥러닝

[머신러닝] #4 신경망 학습 #2

by 돼지왕 왕돼지 2018. 7. 6.
반응형

[머신러닝] #4 신경망 학습 #2




"Deep Learning from Scratch” 책을 보고 제가 필요한 내용만 정리한 내용입니다.

자세한 내용은 책을 구매해서 보세요~

2층 신경망 클래스 구현, backpropagation, Choice, EPOCH, Grad, gradient, gradient ascent method, gradient descent method, gradient method, hyper parameter, learning rate, over fitting, plateau, randn, random, saddle point, SGD, stochastic gradient descent, zeros_like, 가중치, 가중치 매개변수, 가중치 매개변수 갱신, 가중치 학습, 가중치와 편향, 경사 상승법, 경사 하강법, 경사법, 고원, 극소값, 기울기, 기울기 고속, 기울기 산출, 기울기 최소값, 매개변수 갱신, 매개변수 갱신 량, 매개변수 공간, 미니 배치 학습 구현하기, 미니배치, 반복, 발산, 배개변수의 기울기, 범용 능력, 벡터 그래프, 손실 함수, 손실 함수 최소값, 손실 함수', 수치 미분, 시험 데이터, 시험 데이터로 평가하기, 신경망, 신경망 학습, 신경망 학습 절차, 신경망에서의 기울기, 안장점, 에폭, 오버 피팅, 오차역전파법, 전제, 직접 설정 매개변수, 초매개변수, 최소값, 최적의 매개변수, 편미분 백터, 편향, 편향 학습, 플래토, 하이퍼파라미터, 학습 알고리즘 구현하기, 학습 정체기, 학습률, 학습률 값, 확률적 경사 하강법, 훈련 데이터


4.4. 기울기


-

x0 와 x1 의 (두 변수의) 편미분을 동시에 계산하는, 모든 변수의 편미분을 벡터로 정리한 것을 기울기(gradient)라고 한다.

def numerical_gradient(f, x):

    h = 1e-4

    grad = np.zeros_like(x) # x 와 형상이 같은 배열을 생성


    for idx in range(x.size):

        tmp_val = x[idx]


        # f(x+h) 계산

        x[idx] = tmp_val + h

        fxh1 = f(x)


        # f(x-h) 계산

        x[idx] = tmp_val - h

        fxh2 = f(x)


        grad[idx] = (fxh1 - fxh2) / 2*h

        x[idx] = tmp_val  # 값 복원


    return grad



-

편미분의 기울기에 마이너스를 붙인 백터를 그려보면 방향을 가진 벡터(화살표)로 그려진다. ( 아래 그래프는 마이너스를 안 붙여 바깥방향, 책에는 마이너스를 붙여 안쪽으로 향하는 그래프가 있다 ) 

기울기의 함수는 가장 낮은 장소(최솟값)을 가르키는 형상이다.

가장 낮은 곳에서 멀어질수록 화살표의 크기가 커짐을 알 수 있다.

2층 신경망 클래스 구현, backpropagation, Choice, EPOCH, Grad, gradient, gradient ascent method, gradient descent method, gradient method, hyper parameter, learning rate, over fitting, plateau, randn, random, saddle point, SGD, stochastic gradient descent, zeros_like, 가중치, 가중치 매개변수, 가중치 매개변수 갱신, 가중치 학습, 가중치와 편향, 경사 상승법, 경사 하강법, 경사법, 고원, 극소값, 기울기, 기울기 고속, 기울기 산출, 기울기 최소값, 매개변수 갱신, 매개변수 갱신 량, 매개변수 공간, 미니 배치 학습 구현하기, 미니배치, 반복, 발산, 배개변수의 기울기, 범용 능력, 벡터 그래프, 손실 함수, 손실 함수 최소값, 손실 함수', 수치 미분, 시험 데이터, 시험 데이터로 평가하기, 신경망, 신경망 학습, 신경망 학습 절차, 신경망에서의 기울기, 안장점, 에폭, 오버 피팅, 오차역전파법, 전제, 직접 설정 매개변수, 초매개변수, 최소값, 최적의 매개변수, 편미분 백터, 편향, 편향 학습, 플래토, 하이퍼파라미터, 학습 알고리즘 구현하기, 학습 정체기, 학습률, 학습률 값, 확률적 경사 하강법, 훈련 데이터

-

실제로 모든 벡터가 항상 기울기가 가장 낮은 장소를 가르키지 않는다.

사실 기울기는 각 지점에서 낮아지는 방향을 가르킨다.

더 정확히 말하자면 기울기가 가르키는 쪽은 “각 장소”에서 함수의 출력 값을 가장 크게 줄이는 방향이다.




4.4.1. 경사법(경사 하강법)


-

기계학습 문제 대부분은 학습 단계에서 최적의 매개변수를 찾아낸다.

신경망 역시 최적의 매개변수(가중치와 편향)를 학습 시에 찾아야 한다.

여기서 최적이란 손실 함수가 최솟값이 될 때의 매개변수 값이다.

그러나 일반적인 문제의 손실 함수는 매우 복잡하다.

매개변수 공간이 광대하여 어디가 최솟값이 되는 곳인지를 알아내기가 만만치 않다.

이런 상황에서 기울기를 잘 이용해 함수의 최솟값(또는 가능한 한 작은 값)을 찾으려는 것이 경사법이다.



-

주의할 점은 각 지점에서 함수의 값을 낮추는 방안을 제시하는 지표가 기울기라는 것과,

기울기가 가리키는 곳에 정말 함수의 최솟값이 있는지, 즉 그쪽이 정말로 나아갈 방향인지는 보장할 수 없다.

실제로 복잡한 함수에서는 기울기가 가르키는 방향에 최솟값이 없는 경우가 대부분이다.



-

함수가 극소값, 최소값 또는 안장점(saddle point)이 되는 장소에서는 기울기가 0이다.

극소값은 국소적인 최소값, 즉 한정된 범위에서의 최솟값인 점이다.

안장점은 어느 방향에서 보면 극대값이고 다른 방향에서 보면 극소값이 되는 점이다.

경사법은 기울기가 0인 장소를 찾지만 그것이 반드시 최소값이라고는 할 수 없다.(극소값이나 안장점일 가능성이 있다.)

또, 복잡하고 찌그러진 모양의 함수라면(대부분) 평평한 곳으로 파고들면서 고원(plateau, 플래토)이라 하는, 학습이 진행되지 않는 정체기에 빠질 수 있다.



-

기울어진 방향이 꼭 최소값을 가리키는 것은 아니나, 그 방향으로 가야 함수의 값을 줄일 수 있다.

그래서 최소값이 되는 장소를 찾는 문제(아니면 가능한 한 작은 값이 되는 장소를 찾는 문제)에서는 기울기 정보를 단서로 나아갈 방향을 정해야 한다.



-

경사법은 현 위치에서 기울어진 방향으로 일정 거리만큼 이동한다.

그런 다음 이동한 곳에서도 마찬가지로 기울기를 구하고, 또 그 기울어진 방향으로 나아가기를 반복한다.

이렇게 해서 함수의 값을 점차 줄이는 것이 경사법(gradient method)이다.

경사법은 기계학습을 최적화하는 데 흔히 쓰는 방법이다.

특히 신경망 학습에는 경사법을 많이 사용한다.



-

경사법은 최소값을 찾느냐, 최대값을 찾느냐에 따라 이름이 다르다.

최소값을 찾는 것을 경사 하강법(gradient descent method), 최대값을 찾는 것을 경사 상승법(gradient ascent method)라고 한다.

다만 손실 함수의 부호를 반전시키면 최소값을 찾는 문제와 최대값을 찾는 문제는 같은 것이니 하강이냐 상승이냐는 본질적으로는 중요하지 않다.

일반적으로 신경망(딥러닝) 분야에서의 경사법은 경사 하강법으로 등장할 때가 많다.



-

2층 신경망 클래스 구현, backpropagation, Choice, EPOCH, Grad, gradient, gradient ascent method, gradient descent method, gradient method, hyper parameter, learning rate, over fitting, plateau, randn, random, saddle point, SGD, stochastic gradient descent, zeros_like, 가중치, 가중치 매개변수, 가중치 매개변수 갱신, 가중치 학습, 가중치와 편향, 경사 상승법, 경사 하강법, 경사법, 고원, 극소값, 기울기, 기울기 고속, 기울기 산출, 기울기 최소값, 매개변수 갱신, 매개변수 갱신 량, 매개변수 공간, 미니 배치 학습 구현하기, 미니배치, 반복, 발산, 배개변수의 기울기, 범용 능력, 벡터 그래프, 손실 함수, 손실 함수 최소값, 손실 함수', 수치 미분, 시험 데이터, 시험 데이터로 평가하기, 신경망, 신경망 학습, 신경망 학습 절차, 신경망에서의 기울기, 안장점, 에폭, 오버 피팅, 오차역전파법, 전제, 직접 설정 매개변수, 초매개변수, 최소값, 최적의 매개변수, 편미분 백터, 편향, 편향 학습, 플래토, 하이퍼파라미터, 학습 알고리즘 구현하기, 학습 정체기, 학습률, 학습률 값, 확률적 경사 하강법, 훈련 데이터

경사법을 수식으로 나타낸 것은 위와 같다.

알파는 갱신하는 양을 나타내는데, 이를 신경망 학습에서는 “학습률(learning rate)” 라고 한다.

한 번의 학습으로 얼마만큼 학습해야 할지, 즉 매개변수 값을 얼마나 갱신하느냐를 정하는 것이 학습률이다.


위의 식은 1회에 해당하는 갱신이고, 이 단계를 반복한다.

변수의 값을 갱신하는 단계를 여러 번 반복하면서 서서히 함수의 값을 줄이는 것이다.


학습률의 값은 0.01 이나 0.001 등 미리 특정 값으로 정해두어야 하는데, 일반적으로 이 값이 너무 크거나 작으면 “좋은 장소” 를 찾아갈 수 없다.

신경망 학습에서는 보통 이 학습률 값을 변경하면서 올바르게 학습하고 있는지를 확인하면서 진행한다.



-

def gradient_descent(f, init_x, lr=0.01, step_num=100):

    x = init_x

    

    for i in range(step_num):

        grad = numerical_gradient(f, x)

        x -= lr * grad

    return x


f 는 최적화하려는 함수, init_x 는 x 초기값, lr 은 learning rate, step_num 은 경사법에 따른 반복 횟수.



-

학습률이 너무 크면 큰 값으로 발산해버리고, 반대로 너무 작으면 거의 갱신되지 않은 채 끝날 수 있다.



-

학습률 같은 매개변수를 하이퍼파라미터(hyper parameter, 초매개변수)라고 한다.

이는 가중치와 편향 같은 신경망의 매개변수와는 성질이 다른 매개변수이다.

신경망의 가중치 매개변수는 훈련 데이터와 학습 알고리즘에 의해서 ‘자동’으로 획득되는 매개변수인 반면, 학슬률 같은 하이퍼파라미터는 사람이 직접 설정해야 하는 매개변수인 것이다.

일반적으로 이들 하이퍼파라미터는 여러 후보 값 중에서 시험을 통해 가장 잘 학습하는 값을 찾는 과정을 거쳐야 한다.




4.4.2 신경망에서의 기울기


-

신경망 학습에서도 기울기를 구해야 한다.

여기서 말하는 기울기는 가중치 매개변수에 대한 손실 함수의 기울기이다.

2층 신경망 클래스 구현, backpropagation, Choice, EPOCH, Grad, gradient, gradient ascent method, gradient descent method, gradient method, hyper parameter, learning rate, over fitting, plateau, randn, random, saddle point, SGD, stochastic gradient descent, zeros_like, 가중치, 가중치 매개변수, 가중치 매개변수 갱신, 가중치 학습, 가중치와 편향, 경사 상승법, 경사 하강법, 경사법, 고원, 극소값, 기울기, 기울기 고속, 기울기 산출, 기울기 최소값, 매개변수 갱신, 매개변수 갱신 량, 매개변수 공간, 미니 배치 학습 구현하기, 미니배치, 반복, 발산, 배개변수의 기울기, 범용 능력, 벡터 그래프, 손실 함수, 손실 함수 최소값, 손실 함수', 수치 미분, 시험 데이터, 시험 데이터로 평가하기, 신경망, 신경망 학습, 신경망 학습 절차, 신경망에서의 기울기, 안장점, 에폭, 오버 피팅, 오차역전파법, 전제, 직접 설정 매개변수, 초매개변수, 최소값, 최적의 매개변수, 편미분 백터, 편향, 편향 학습, 플래토, 하이퍼파라미터, 학습 알고리즘 구현하기, 학습 정체기, 학습률, 학습률 값, 확률적 경사 하강법, 훈련 데이터

이는 각각의 원소에 관한 편미분이다.


예를 들어 w11 을 조금 변경했을 때 손실 함수 E 가 얼마나 변화하느냐를 나타낸다.



-

ex)

class simpleNet:

    def __init__(self):

        self.W = np.random.randn(2,3) # 정규분포로 초기화 (mean 0, variance 1 인 값으로 2 X 3 matrix 를 만든다. )


    def predict(self, x):

        return np.dot(x, self.W)


    def loss(self, x, t):

        z = self.predict(x)

        y = softmax(x)

        loss = cross_entropy_error(y, t)

        return loss


def f(W):

    return net.loss(x, t)

# f = lambda w: net.loss(x,t) 로도 코딩 할 수도 있다.


dW = numerical_gradient(f, net.W) # loss function 에 대한 weight 로의 편미분






4.5. 학습 알고리즘 구현하기


-

신경망 학습 절차는 다음과 같다.


전제

    신경망에는 적용 가능한 가중치와 편향이 있고, 이 가중치와 편향을 훈련 데이터에 적응하도록 조정하는 과정을 “학습”이라 한다. 신경망 학습은 다음과 같이 4단계로 수행한다.


1단계 - 미니배치

    훈련 데이터 중 일부를 무작위로 가져온다.

    이렇게 선별한 데이터를 미니배치라 하며, 그 미니배치의 손실함수 값을 줄이는 것이 목표이다.


2단계 - 기울기 산출

    미니배치의 손실 함수 값을 줄이기 위해 각 가중치 매개변수의 기울기를 구한다.

    기울기는 손실 함수의 값을 가장 작게 하는 방향을 제시한다.


3단계 - 매개변수 갱신

    가중치 매개변수를 기울기 방향으로 아주 조금 갱신한다.


4단계 - 반복

    1~3단계 반복.


이는 경사 하강법으로 매개변수를 갱신하는 방법이며, 이때 데이터를 미니배치로 무작위로 선정하기 때문에 확률적 경사 하강법(stochastic gradient descent, SGD) 라고 부른다.

대부분의 딥러닝 프레임워크는 확률적 경사 하강법의 영어 머리글자를 딴 SGD 라는 함수로 이 기능을 구현하고 있다.




4.5.1. 2층 신경망 클래스 구현하기


-

class TwoLayerNet:

    # hidden_size 는 hidden layer(1층)의 node 갯수

    def __init__(self, input_size, hidden_size, output_size, weight_init_std=0.01):

        # 가중치 초기화

        self.params = { }

        self.params[‘W1’] = weight_init_std * np.random.randn(input_size, hidden_size)

        self.params[‘b1’] = np.zeros(hidden_size)

        self.params[‘W2’] = weight_init_std * np.random.randn(hidden_size, output_size)

        self.params[‘b2’] = np.zeros(output_size)


    def predict(self, x):

        W1, W2 = self.params[‘W1’], self.params[‘W2’] # 첫번째, 두번째 층의 가중치

        b1, b2 = self.params[‘b1’], self.params[‘b2’] # 첫번째, 두번째 층의 편향

        

        a1 = np.dot(x, W1) + b1

        z1 = sigmoid(a1)


        a2 = np.dot(z1, W2) + b2

        y = softmax(a2)


        return y


def loss(self, x, t):

    y = self.predict(x)

    return cross_entropy_error(y, t)


def accuracy(self, x, t):

    y = self.predict(x)

    y = np.argmax(y, axis=1)

    t = np.argmax(t, axis=1)


    accuracy = np.sum(y == t) / float(x.shape[0])

    return accuracy


def numerical_gradient(self, x, t):

    loss_W = lambda W: self.loss(x,t)


    grads = { }

    grads[‘W1’] = numerical_gradient(loss_W, self.params[‘W1’]) # 첫번째 층의 가중치의 기울기

    grads[‘b1’] = numerical_gradient(loss_W, self.params[‘b1’]) # 첫번째 층의 편향의 기울기

    grads[‘W2’] = numerical_gradient(loss_W, self.params[‘W2’]) # 두번째 층의 가중치의 기울기

    grads[‘b2’] = numerical_gradient(loss_W, self.params[‘b2’]) # 두번째 층의 편향의 기울기


    return grads



-

가중치 매개변수의 초기값을 무엇으로 설정하느냐가 신경망 학습의 성공을 좌우하기도 한다.




4.5.2. 미니배치 학습 구현하기


-

(x_train, t_train), (x_test, t_test) = load_mnist(normalize=True, one_hot_label=True)


train_loss_list = [ ]


# 하이퍼 파라미터

iters_num = 10000

train_size = x_train.shape[0]

batch_size = 100

learning_rate = 0.1

network = TwoLayerNet(input_size=784, hidden_size=50, output_size=10)


for i in range(iters_num):

    #미니배치 획득

    batch_mask = np.random.choice(train_size, batch_size)

    x_batch = x_train[batch_mask]

    t_batch = t_train[batch_mask]


    #기울기 계산

    grad = network.numerical_gradient(x_batch, t_batch) # 추후 다루는 고속 미분방법인 오차역전파법을 사용하면 더 좋다


    #매개변수 갱신

    for key in (‘W1’, ‘b1’, ‘W2’, ‘b2’):

        network.params[key] -= learning_rate * grad[key]


    #학습 경과 기록

    loss = network.loss(x_batch, t_batch)

    train_loss_list.append(loss)




4.5.3. 시험 데이터로 평가하기


-

훈련 데이터의 손실 함수 값이 작아지는 것은 신경망이 잘 학습하고 있다는 방증이지만, 이 결과만으로는 다른 데이터셋에서도 비슷한 실력을 발휘할지는 확실하지 않다.

신경망 학습에서는 훈련 데이터 외의 데이터를 올바르게 인식하는지를 확인해야 한다. 다른 말로 “오버피팅”을 일으키지 않는지 확인해야 한다.

오버피팅되었다는 것은, 예를 들어 훈련 데이터에 포함된 이미지만 제대로 구분하고, 그렇지 않은 이미지는 식별할 수 없다는 뜻이다.



-

신경망 학습의 원래 목표는 범용 능력을 익히는 것이다.

범용 능력을 평가하려면 훈련 데이터에 포함되지 않은 데이터를 사용해 평가해봐야 한다.



-

에폭(epoch)은 하나의 단위이다.

1에폭은 학습에서 훈련 데이터를 모두 소진했을 때의 횟수에 해당한다.

예를 들어 훈련 데이터 10,000개를 100개의 미니배치로 학습할 경우, 확률적 경사 하강법을 100회 반복하면 모든 훈련 데이터를 ‘소진’한 게 된다.

이 경우 100회가 1에폭이 된다.



-

iter_per_epoch = max(train_size/batch_size, 1)


for i in range(iters_num):

...

# 1 에폭당 정확도 계산

if i % iter_per_epoch == 0:

    train_acc = network.accuracy(x_train, t_train)

    test_acc = network.accuracy(x_test, t_test)

    train_acc_list.append(train_acc)

    train_acc_list.append(test_acc)





4.6. 정리


기계학습에서 사용하는 데이터셋은 훈련 데이터와 시험 데이터로 나눠 사용한다.

훈련 데이터로 학습한 모델의 범용 능력을 시험 데이터로 평가한다.

신경망 학습은 손실 함수를 지표로, 손실 함수의 값이 작아지는 방향으로 가중치 매개변수를 갱신한다.

가중치 매개변수를 갱신할 때는 가중치 매개변수의 기울기를 이용하고, 기울어진 방향으로 가중치의 값을 갱신하는 작업을 반복한다.

아주 작은 값을 주었을 때의 차분으로 미분하는 것을 수치 미분이라고 한다.

수치 미분을 이용해 가중치 매개변수의 기울기를 구할 수 있다.

수치 미분을 이용한 계산에는 시간이 걸리지만, 그 구현은 간단하다. 한편, 다음 장에서 구현하는 (다소 복잡한) 오차역전파법은 기울기를 고속으로 구할 수 있다.




반응형

댓글