※ 본 글은 한경훈 교수님의 머신러닝 강의를 정리, 보충한 글입니다. ※
다층 신경망의 구조
- Input Layer (입력층) : 데이터가 입력되는 계층
- Hidden Layer (은닉층) : 데이터가 전달되는 계층
- Output Layer (출력층) : 데이터가 출력되는 계층
- Weights : 전/후 Units를 잇는 화살표, 각 Units의 연결 강도를 결정하는 가중치
계산층(은닉층, 출력층)이 둘 이상인 신경망을 다층 신경망 DNN이라고 부른다.
단층신경망은 입력층과 출력층이 각각 하나로, 계산층인 출력층 하나뿐이다.
모든 계산층이 자신의 계산 결과를 입력에서 출력으로의 순방향으로만 전달하는 구조를
순방향 신경망(feed-forward network)이라고 부른다.
기본적인 행렬 연산
다층 신경망은 행렬의 연산으로 구현될 수 있다.
행렬이란?
가로 = 행 = row
세로 = 열 = column
행렬이 좌표로 표현되면 (행, 열) or (row, column)로 표현된다.
덧셈, 뺄셈
같은 위치끼리 연산한다.
상수배
모든 원소에 상수를 곱한다.
곱셈
행렬 A와 행렬 B의 곱셈은 AB라고 표현한다.
이때, A의 열과 B의 행의 개수가 동일해야 곱셈이 가능하다.
A(m x n) 행렬과 B(n x l)의 곱셈은 행렬 C(m x l)가 된다.
행렬은 교환 법칙이 성립하지 않는다. ex. AB ≠ BA
T (transpose)
행과 열을 대각선을 기준으로 뒤집는다. 기하학적으로 뒤집는 것보다 행과 열을 뒤바꿔준다고 생각하는 게 이해하기 쉽다.
다층 신경망의 표기
다층 신경망에서는 각 층마다 편향과 가중치가 각각 다르므로,
윗 첨자(k)로 몇 층으로 전달하는지 표기해준다. (한마디로 출발층이 아니라 도착층)
밑 첨자로는 출발 층의 몇 번째 뉴런인지, 도착 층의 몇번째 뉴런인지를 표기해준다.
ex. 입력층에서 1층으로 신호 전달
도착층이 1층이므로 윗 첨자는 (1)로 표기하고
밑 첨자로는 입력층의 n번째 뉴런에서 1층의 m번째 뉴런으로 가는 것을 nm으로 표기하였다.
오타 : 아래 그림에서 w12가 w21로 바뀌어야 함.
다층 신경망의 계산
다층 신경망의 입력과 출력, 편향과 가중치가 모두 행렬임을 고려하여
표기를 기반으로 다음과 같은 식을 세울 수 있다.
다층 신경망의 구현
# 학습이 진행되면 가중치나 편향의 값이 바뀌는데,
# 바뀌기 전에 설정한 뉴런이므로 `init` 이라 표현함
def init_network():
network = {} # 딕셔너리
#1층(은닉층): 2개의 입력을 받아 3개의 노드로 연결
network['W1'] = np.array([[0.1, 0.3, 0.5], # w11 w12 w13
[0.2, 0.4, 0.6]]) # w21 w22 w23
network['b1'] = np.array([0.1, 0.2, 0.3])
#2층(은닉층): 3개의 입력을 받아 2개의 노드로 연결
network['W2'] = np.array([[0.1, 0.4], # w11 w12
[0.2, 0.5], # w21 w22
[0.3, 0.6]]) # w31 w32
network['b2'] = np.array([0.1, 0.2])
#3층(출력층):
network['W3'] = np.array([[0.1, 0.3], # w11 w12
[0.2, 0.4]]) # w21 w22
network['b3'] = np.array([0.1, 0.2])
return network
# forward(순방향)
def forward(network, x):
W1, W2, W3 = network['W1'], network['W2'], network['W3']
b1, b2, b3 = network['b1'], network['b2'], network['b3']
# 1층의 가중치 연산 및 활성화 함수(시그모이드)통과
a1 = np.dot(x, W1) +b1
# np.dot은 행렬을 곱하는 함수이다.
# [x1*w11 + x2*w21 + b1, x1*w12 + x2*w22 + b2, x1*w13 + x2*w23 + b3]
# [1.0*0.1 + 0.5*0.2 + 0.1, 1.0*0.3 + 0.5*0.4 + 0.2, 1.0*0.5 + 0.5*0.6 + 0.3]
print(a1)
z1 = sigmoid(a1)
# 2층의 가중치 연산 및 활성화 함수(시그모이드)통과
a2 = np.dot(z1, W2) +b2
z2 = sigmoid(a2)
# 3층의 가중치 연산 및 출력
# 마지막 층은 출력층이므로 sigmoid 말고
# 원래는 확률변수로 바꿔주는 softmax함수를 써야 하는데 일단은 항등함수 사용
a3 = np.dot(z2, W3) + b3
y = a3
# 가중치, 편향이 설정된 딕셔너리 리턴
network = init_network()
# 입력할 값 설정
x = np.array([1.0, 0.5])
# 입력, 가중치, 편항 기반으로 연산 수행
a3 = forward(network, x)
y = identify_function(a3)
print(y)
Softmax
소프트 맥스 함수란, 출력층에서 사용되는 활성화 함수이다.
입력받은 벡터를 확률 벡터로 바꿔주기 위해 사용된다.
확률 벡터는 양수이며, 총합이 1이 되는데 이를 만족하기 위해서
exp를 적용하여 모든 원소를 양수로 바꿔주고, 산술평균을 적용하여 총합이 1이 되게 한다.
모든 원소에 같은 값을 가감해도 동일한 값이 나온다는 특징이 있으므로
전체 원소에 동일하게 max 값을 빼줌으로써 overflow를 해결할 수 있다.
x = np.array([1020,1000,980]);
a = np.exp(x)/np.sum(exp(x)); # overflow 발생
x = x - np.max(x); # overflow 해결 : [0,-20,-40]
a = np.exp(x)/np.sum(exp(x));
softmax 함수 구현
def softmax(x):
x = x - np.max(x); # overflow 해결
return np.exp(x)/np.sum(np.exp(x));
신호 전달 과정
신호를 입력받아 가중치를 곱하고 편향을 더하는 연산을 Affine 변환(or 연산)이라 부른다.
Affine 변환 후 sigmoid 함수를 실행하고 이 과정을 출력층까지 반복한다.
출력층에선 sigmoid 함수 대신 softmax 함수로 확률변수를 출력한다.
이러한 구조가 가장 기본적인 인공신경망의 구조이다.
'ML' 카테고리의 다른 글
[ML] 딥러닝 1 - 6강 손실함수 (0) | 2021.07.23 |
---|---|
[ML] 딥러닝 1 - 5강 신경망 구현 (0) | 2021.07.23 |
[ML] 딥러닝 1 - 4강 MNIST (0) | 2021.07.17 |
[ML] 딥러닝 1 - 2강 활성화 함수 (1) | 2021.07.13 |
[ML] 딥러닝 1 - 1강 퍼셉트론 (1) | 2021.07.11 |