ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [TensorFlow] 텐서플로우 2.0 예제 01 (Colab 환경)
    Deep Learning 공부자료/DL\ML\AI 구현 및 실습 2020. 5. 26. 22:24

    Tensorflow를 import하기

    아래처럼 텐서플로우 라이브러리를 프로그램에 import 해줍니다. 처음이라 설치하는 내용까지 같이 들어간 거고,

    그냥 import tensorflow as tf만 입력해도 됩니다.

     

    Tensorflow로 난수 생성하기

    Uniform 사용해서 난수 생성하기

    uniform 함수는 인자를 총 세 개 받는데,

    첫번째 인자는 shape으로, 반환되는 난수의 차원을 의미하고,

    두번째 인자와 세번째 인자는 각각 최솟값과 최댓값을 의미한다.

     

    발생시킨 난수를 출력해보면, Tensor의 내용이 출력된다.

     

    Noraml 사용해서 난수 생성하기

    normal 함수도 인자를 총 세 개 받으며, 그 구성을 Uniform과 약간 차이가 있다. 

    첫번째 인자 shpae은 uniform에서와 마찬가지로 차원을 의미한다.

    두번째 인자는 mean으로 정규분포의 평균값을 의미하며,

    세번째 인자는 standard deviation으로 정규분포의 표준편차를 의미한다. 

    보통을 두번째 인자와 세번째 인자를 각각 0과 1로 설정하여 표준 정규 분포를 사용한다. 

     

     

    Activation Function 정의하기

    신경망의 뉴런들은 activation function (활성함수)를 통과하여 output을 내게 되는데,

    이 때 다양한 종류의 함수들이 사용된다.

     

    이 중에서 가장 흔하게 접할 수 있는 Sigmoid function과 가장 많이 사용되는 ReLu function을 구현해보자. 

    Sigmoid Function

    우리가 네트워크에서 sigmoid를 사용하게 되는 경우는 보통 output의 범위를 한정 지어주기 위해서!

    [0, 1] 로 한정되는 범위 덕에 확률을 결과값으로 내야할 경우에 유용하다. 

     

    하지만 simoid 함수가 갖고 있는 치명적인 문제점들이 있는데,

    가장 심각한 문제는 simgoid 함수에 Input으로 들어가는 값이 너무 작거나 클 경우, gradient가

    사라져서 학습의 속도를 현저히 느리게 만들어 버린다. 

     

    또한 output의 평균이 0.5로 형성되는데, zero-mean을 이루지 않을 경우에 

    지그재그 그래프를 그리며 느리고 효율적이지 않은 학습을 하게 된다. 

     

    심지어 계산 속도도 exponention function이 사용되어 느리다. 

     

     

    ReLu Function

    위에서 언급한 sigmoid의 문제점을 해결하기 위해서 등장한 함수이다. 

    심플하지만, sigmoid에 비해서 장점이 매우 많아서 거의 가장 많이 사용되는 activation function이라고 보면 된다. 

     

    왼쪽의 gradient가 소실되긴 하지만, 오른편의 gradient는 계속 잘 살아 있고,

    계산 속도가 매우 빠르다. 

     

    하지만 여전히 zero-centered 문제를 해결하지 못하고 있고,

    왼편의 gradient가 kill 되는 문제가 있다.

     

    이 두번째 문제를 해결하기 위해서 leaky ReLu가 제안된다.

    Activation function에 관한 내용은 추후에 좀 더 자세히 다루도록 하겠다. 

     

     

    Neuron 생성하기

    Sigmoid 사용하는 뉴런 만들기

    가중치는 normal distribution을 이용하여 초기화했고,

    단순한 정수 하나를 input과 output으로 하는 뉴런을 생성해 보았다.

     

    ReLu 사용하는 뉴런 만들기

    마찬가지로 가중치는 normal distribution을 이용하여 초기화했고,

    또한 마찬가지로 단순한 정수 하나를 input과 output으로 하는 뉴런을 생성해 보았다.

     

    sigmoid를 사용했을 때와 달리 결과가 array로 표현되는데,

    그 이유는 ReLu 함수가 numpy를 활용하기 때문이다. 

     

    우리의 목표는 output이 y 값에 점차 가까워지도록 하는 것이다. 

    이는 '학습'을 통해 이뤄나가는데, 학습 과정에서 weight를 update해 가며, input을 output으로 매칭 시키기 위한 최적의 weight를 찾아내는 것이다.

     

    모델(?) 학습 시키기

    모델에 물음표를 붙인 것은,,, 이건 모델이라고 하기엔 너무 뉴런 하나짜리라,, ㅎㅎ

    무튼 최적의 weight를 찾기 위해서 Gradient Descent Algorithm을 활용하겠다. 

     

    적절한 learning rate를 설정하여, 초기 weight 값에서 loss function의 기울기를 계산하여,

    Weight를 그 기울기의 반대 방향으로 이동시킨다. 이 과정을 반복하다보면,

    우리가 원하는 loss function을 최소화 시키는 weight를 찾을 수 있다. 

     

    이때 learning rate와 초기 weight 값을 잘 정하는 것이 중요하다. 

     

    weight의 update는  W = W + input * learning rate * | y - output| 를 사용하겠다. 

    (원래는 미분도 사용하는데, 여기서는 그냥..ㅎㅎ)

     

    Sigmoid 사용하는 뉴런 학습시키기

    learning rate는 0.1로 하였지만, 사실 학습률은 hyper-parameter로, 최적의 learning rate도 찾아줘야한다.

    18 line에서 weight update가 이뤄진다. 

     

    학습이 진행됨에 따라, error의 절댓값이 점점 줄어 드는 것을 확인 할 수 있다 .

     

    ReLu 사용하는 뉴런 학습시키기

    Sigmoid 때랑은 다르게, 안정적으로 loss가 줄어들지 않는데, 아마도 learning rate 문제가 아닐까 싶다. 

    지금은 그냥 구현에 의미를 두는 것으로!

     

     

    Bias 정의하기

    input을 제대로 초기화 해주지 않으면, 학습이 이뤄지지 않는 상황이 생길 수 있는데,

    이는 gradient descent algorithm과 같은 알고리즘들의 고질적인 문제인 local minima 등이 원인일 것이다.

     

    이런 문제를 해결해주기 위해서 bias (편향)을 활용한다. 

     

     

    12 line에서 bias를 weight 초기화 때와 마찬가지로 normal distribution을 이용하여 초기화 해줬다. 

    20 line에서 activation function의 intput으로 연산의 결과를 넣어 줄 때, bias를 더해주었다. 

     

    bias도 weight와 마찬가지로 학습이 진행됨에 따라 loss를 최소화 시키기 위해서 update 해줘야 하며

    27 line에서 update 해 주었다. 

     

    결과를 보면 위에서 bias를 사용하지 않았을 때와 달리, error가 안정적으로 감소하는 것을 확인할 수 있다. 

     

     

    댓글

Written by Geulleun