[비전공자를 위한 딥러닝] 파이썬 실습 - 시그모이드, 렐루 구현



이 글에서는 파이썬 설치와 실행에 대해서 다루지 않습니다.
대신 웹 브라우저에서 간편하게 코딩할 수 있는 무료 플랫폼 repl.it을 사용해 예시를 구성하였습니다.
replit.com




앞서 살펴보았듯이, 함수(function)는 입력을 받아 특정한 처리를 한 뒤 출력한다. 


파이썬에서는 함수를 다음과 같이 정의(define)할 수 있다.


def 뒤에는 스페이스 1칸,
콜론(:) 다음 두번 째 줄 시작에는 들여쓰기(indent).
들여쓰기는 tab 키를 눌러도 되고 스페이스를 4번 입력해도 된다.
설정에 따라 스페이스 2칸을 들여쓰기로 지정할 수도 있다.


예를 들어, 다음과 같은 함수를 살펴보자.

이 함수는 x 라는 입력이 들어왔을 때 2x + 4 라는 출력을 반환한다.



이 함수를 그래프로 표현하면 다음과 같은 직선이 된다.

x축은 입력이고, y축은 출력을 의미한다.


이 함수를 파이썬으로 구현해보자.
위의 형식에 따라 함수 이름, 입력, 출력을 넣어주면 된다. 함수 이름은 파이썬 함수명 규칙만 만족한다면 어떤 것으로 지정해도 상관 없다. 우선 예제에서는 단순히 'function'으로 해보겠다.


이처럼 직관적이고 간단명료하게 코딩이 가능하는 것이 파이썬이 사랑받는 이유 중 하나이다.


자, 이제 시그모이드 함수를 구현해보자.
시그모이드의 수식은 다음과 같다.



여기서 e의 -x승이라는 기호가 등장하는데, 전혀 어렵게 생각할 필요가 없다.
e란 자연상수로서 2.718... 이라는 값을 가지는 하나의 상수(constant), 즉 고정된 수로 생각하면 된다. 직관적으로 파악하기 위해 2.7이라는 값으로 반올림해보자.


x에 0이 들어온다면 e^(-x)는 2.7의 0승, 즉 1이 된다.
따라서 전체 식은 1 / (1 + 1) 이 되고 그 값은 0.5다.

x에 -1000이 들어온다면 2.7의 1000승이라는 엄청나게 큰 수가 된다.
따라서 전체 식은 1 / (1 + 큰 수) 가 되고  그 값은 0에 가까운 작은 수가 된다.

x에 1000이 들어온다면 2.7의 -1000승이라는 아주 작은 수가 된다.
따라서 전체 식은 1 / (1 + 작은 수) 가 되고 그 값은 1에 가까운 수가 된다.


그래프와 함께 그 의미를 살펴본다면 쉽게 이해할 수 있을 것이다.



시그모이드 함수의 입력과 출력은 다음과 같다.


여기서 exp는 지수함수(exponential function)의 앞글자에서 온 것이며, exp(x)는 e의 x승을 의미한다.
또한 분수를 표현할 때 파이썬은 '/' 기호를 사용한다.


np는 numpy라는 라이브러리에 존재하는 exp 함수를 사용한다는 뜻인데, 파이썬에서는 라이브러리를 불러올 때 코드의 제일 윗 부분에 다음과 같이 적어준다.

따라서 시그모이드 함수의 전체 코드는 다음과 같다.


exp 함수는 numpy 라이브러리 말고도 math 라이브러리에도 존재한다. math의 경우 따로 설치를 하지 않아도 사용이 가능한 표준 라이브러리이기 때문에, numpy가 설치되어 있지 않다면 아래와 같은 코드로 실행해도 결과는 동일하다. (repl.it의 경우는 numpy 라이브러리가 설치되어 있다.)




자, 이제는 정의된 함수에다가 다양한 숫자를 입력으로 넣어보고 그 출력을 살펴보자. 이렇게 테스트케이스(test case)를 작성해서 구현이 제대로 되었는지 검증할 수 있다.


파이썬에서는 다음과 같이 여러가지 수를 차례차례 넣어보고 그 반환값들을 문자로 출력(print)해볼 수 있다.



시그모이드 함수에 -10 ~ 10 까지 수를 입력했을 때 어떤 출력이 나오는지 살펴보는 코드는 다음과 같이 작성할 수 있다.

" ".format()이라는 포매팅 방법을 사용해 입력 i와 출력 sigmoid(i)를 각각 {} 안에 넣어주었다.

 
Run 버튼을 눌러 실행해보면 다음과 같은 결과를 볼 수 있다.



여기서 e- 와 같은 기호는 자릿수라고 생각하면 된다.
예를 들어 1.00e03은 1000.0을 의미하며, 1.00e-03은 0.001을 의미한다.
1000에도 .0이 굳이 붙는 이유는 컴퓨터 언어에서는 변수를 타입에 따라 다르게 저장하는데, 지금 결과값이 담긴 변수의 형식이 float라는 소숫점 형식이기 때문이다.



보다 널리 쓰이는 활성화함수인 렐루(ReLU) 구현은 과제로 남겨두겠다.
힌트가 있으니 고민하면서 시도해본다면 어렵지 않을 것이다.






=== 과제 ===



어떤 수가 들어와도 0~1 사이의 값을 반환하는 시그모이드의 특징 때문에, 층이 점점 더 쌓이고 신경망이 깊어질 수록 기울기(gradient) 값이 0에 가까워지게 된다.
따라서 시그모이드를 신경망의 비선형 함수로 사용하는 경우에, 층이 점점 많아지고 신경망이 깊어질 때 학습이 잘 이루어지지 않는 현상이 발생한다. 이를 기울기 소실(gradient vanishing)이라고 한다.

렐루를 비선형 함수로 사용하는 경우에는 이 문제가 발생하지 않는다. 렐루는 깊은 신경망이 가능해지면서 인기를 얻기 시작해, 현재 가장 많이 사용되는 활성화 함수로 꼽힌다. 이번 과제로 바로 이 렐루를 구현해보자. 어렵지 않으니 걱정할 필요는 없다.

1. 렐루 수식



2. 렐루 그래프






3. 조건문을 이용한 렐루 구현

파이썬은 'if 조건: (들여쓰기) 실행' 형식으로 조건문을 만들 수 있다.
조건 x < 0 이 만족된다면 0이 반환되고, 그렇지 않다면 (x >= 0) x가 그대로 반환된다.



4. max 함수를 이용한 렐루 구현 (과제)

1) 아래 힌트를 참고해 빈칸에 들어갈 코드를 구현할 것 (한 줄로 작성할 것)
2) 시그모이드 예제에서 했던 것처럼 테스트케이스를 만들어 검증해볼 것




댓글 쓰기

0 댓글