프로그래밍/DeepLearning

[밑바닥부터 시작하는 딥러닝 1] 3. 신경망, 활성화함수

자연대생 2023. 7. 14. 07:13

앞 장에서는 퍼셉트론을 다루며 우리 인간이 적절한 가중치(w)를 설정했다.

하지만 신경망은 학습을 통해 자동으로 가중치를 결정할 수 있다는 장점이 있다.

이번 장에서는 신경망이 입력 데이터가 무엇인지 식별하는 처리 과정을 알아본다.

 

# 신경망

신경망을 그림으로 나타낸 것이다.

가장 왼쪽 줄을 입력층, 맨 오른쪽 줄을 출력층, 중간 줄을 은닉층이라고 한다.

은닉층의 뉴런은 사람 눈에는 보이지 않는다.

이 책에서는 입력층부터 0층, 1층, 2층이라고 한다.

 

이전 장에서는 퍼셉트론을 수식으로 이렇게 나타냈었다.

 

이번 장에서는 좀 더 간결하게 해서 다루도록 한다.

이 h(x)를 활성화 함수(activation function)라고 한다.

 

# 활성화 함수

y 식을 다시 쓰면 이렇게 된다.

가중치가 곱해진 입력 신호의 총합을 계산하고, 그 합을 활성화 함수에 입력해 결과를 내는 2단계로 처리된다.

이 식을 큰 원으로 그려보면 다음과 같다.

 

# 시그모이드 함수

신경망에서 자주 이용하는 활성화 함수이다.

e는 자연 상수로 2.7182...의 값을 갖는 실수이다.

 

신경망에서는 활성화 함수로 시그모이드 함수를 이용하여 신호를 변환하고,

그 변환된 신호를 다음 뉴런에 전달한다.

 

# 계단 함수 구현

임계값을 경계로 출력이 바뀌는 함수를 계단 함수(step function)라고 한다.

퍼셉트론은 활성화 함수로 계단함수를 이용한다.

def step_function(x):
    if x > 0:
        return 1
    else:
        return 0

아주 간단한 구현이지만 넘파이 배열을 인수로 넣을 수 없다.

이를 위해 다음과 같이 작성한다.

 

import numpy as np
def step_function(x):
    y = x > 0
    return y.astype(int)

이 코드는 다음 코드로 설명할 수 있다.

 

x = np.array([-1.0, 1.0, 2.0])
print(x)	# [-1.  1.  2.]
y = x > 0
print(y)	# [False  True  True]
print(y.astype(int))	# [0 1 1]

넘파이 배열 x를 만들고 부등호 연산을 수행시키면

y에 bool 배열이 생성된다.

마지막 코드로 bool 원소들을 int형으로 바꿔준다.

넘파이 배열의 자료형을 변환할 땐 astype() 메서드를 사용한다.

원하는 자료형을 인수로 지정하면 된다.

 

# 계단 함수의 그래프 그리기

import numpy as np
import matplotlib.pylab as plt

def step_function(x):
    y = x > 0
    return y.astype(np.int)

x = np.arange(-5.0, 5.0, 0.1)	# -5.0 ~ 5.0 전까지 0.1 간격의 넘파이 배열 생성 
y = step_function(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1)  # y축 범위 지정
plt.show()

 

0을 경계로 출력이 0, 1로 바뀐다.

 

# 시그모이드 함수 구현

import numpy as np
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

exp(-x)는 e^(-x)에 해당한다.

 

x = np.array([-1.0, 1.0, 2.0])
print(sigmoid(x))	# [0.26894142 0.73105858 0.88079708]

넘파이 배열도 잘 처리하는 것을 볼 수 있다.

 

# 시그모이드 함수 그래프 그리기

import numpy as np
import matplotlib.pylab as plt
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

x = np.arange(-5.0, 5.0, 0.1)   # -5.0 ~ 5.0 전까지 0.1 간격의 넘파이 배열 생성 
y = sigmoid(x)
plt.plot(x, y)
plt.ylim(-0.1, 1.1) # y축 범위 지정
plt.show()

시그모이드 함수는 부드러운 곡선이며 입력에 따라 출력이 연속적으로 변화한다.

이 매끈함이 신경망 학습에서 아주 중요한 역할을 하게 된다.

또한 시그모이드 함수와 계단 함수는 비선형 함수이다.

신경망에서는 활성화 함수로 비선형 함수를 사용해야 한다.

선형 함수를 사용하면 은닉층을 만들 수 없고 단순하게 표현되기 때문이다.

 

# ReLU 함수

import numpy as np
def relu(x):
    return np.maximum(0, x)

ReLU 함수도 신경망에서 많이 쓰인다.

 

ReLU 함수는 입력이 0을 넘으면 그 입력을 그대로 출력하고, 

0 이하이면 0을 출력하는 함수이다.