[케라스] Dense 클래스
13 Feb 2020
Reading time ~3 minutes
김태영님의 블록과 함께 하는 파이썬 딥러닝 케라스
를 학습하며 정리하는 내용입니다.
뉴런의 입출력을 연결해주는 Dense 레이어
케라스의 Dense
클래스는 뉴런의 입력과 출력을 연결해주는 역할을 합니다. 예를 들어 입력 뉴런이 4개, 출력 뉴런이 8개라면 총 연결선은 4 x 8 = 32개 입니다. 각 연결선은 가중치(weight)
를 포함하고 있는데 뉴런의 시냅스처럼 입력 값에 대한 연결 강도와 같습니다.
가중치가 높을 수록 입력값이 출력값에 미치는 영향이 커지고, 낮을 수록 영향이 작아집니다. 성별을 판단하는 문제에서, 뉴런의 출력값이 성별이고, 입력값이 머리길이, 키, 혈액형 등이라고 할 때, 머리길이의 가중치가 높고, 키의 가중치는 중간, 혈액형의 가중치는 가장 낮을 것입니다. 딥러닝 학습과정에서는 이러한 가중치들을 계속 조정을 하며 최적값을 찾아나갑니다.
아래는 Dense 클래스의 사용 예제입니다.
Dense(8, input_dim = 4, kernel_initializer = 'uniform', activation = 'relu')
Dense의 주요 인자들은 아래와 같습니다.
- 첫번째 인자(
units
): 출력 뉴런의 수를 설정합니다. input_dim
: 입력 뉴련의 수를 설정합니다.kernel_initializer
: 가중치를 초기화하는 방법을 설정합니다.uniform
: 균일 분포normal
: 가우시안 분포
activation
: 활성화함수를 설정합니다.linear
: 디폴트 값으로 입력값과 가중치로 계산된 결과 값이 그대로 출력으로 나옵니다sigmoid
: 시그모이드 함수로 이진분류에서 출력층에 주로 쓰입니다softmax
: 소프드맥스 함수로 다중클래스 분류문제에서 출력층에 주로 쓰입니다.relu
: Rectified Linear Unit 함수로 은닉층에서 주로 쓰입니다.
Dense 레이어는 입력 뉴런 수에 관계 없이 출력 뉴런 수를 자연스럽게 설정할 수 있어 출력층으로 많이 사용됩니다. 이진분류 문제에서는 0과 1을 나타내는 출력 뉴런이 1개만 있으면 되기 때문에, 입력값과 가중치의 계산값을 0과 1사이로 표현하는 활성화 함수인 sigmoid를 사용합니다.
# 이진분류 문제에서 입력값이 3개인 경우, 출력층으로 사용된 Dense 레이어
Dense(1, input_dim = 3, activation = 'sigmoid')
이를 레고 블록으로 표현하면 아래 그림과 같습니다. 제일 왼쪽에서는 시냅스강도가 녹색블록으로 표시 되어 있었다면, 가운데 그림에서는 연결선으로 표시되어 있고, 오른쪽에서는 생략되어 있습니다.
다중클래스 분류문제에서는 클래스 수만큼 출력 뉴런이 필요합니다. 만약 세가지 종류로 분류한다면, 활성화함수로 softmax를 사용하여 아래 코드처럼 나타낼 수 있습니다.
# 다중클래스 분류문제에서 입력값이 4개, 출력값이 3개인 경우, 출력층으로 사용된 Dense 레이어
Dense(3, input_dim = 4, activation = 'softmax')
이를 또 레고로 표현하면 아래와 같습니다. 입력신호가 4개이고 출력신호가 3개 이므로 시냅스 강도의 수는 12개 입니다.
Dense 레이어는 출력층 이전의 은닉층으로도 많이 사용됩니다. 영상이 아닌 수치자료 입력 시에는 입력층으로도 많이 사용됩니다. 이 때, 활성화함수로 relu가 많이 사용됩니다. relu는 일반적으로 학습과정에서 역전파 시에 좋은 성능을 나타낸다고 합니다.
# 입력값이 6개, 출력값이 4개인 은닉층으로 사용되는 Dense 레이어
Dense(4, input_dim = 6, activation = 'relu')
이를 레고 블록으로 나타내면 아래와 같습니다.
그리고 입력층이 아닐 때는 그 이전 층의 뉴런 수를 알 수 있기 때문에, 별도로 input_dim 값을 입력하지 않아도 됩니다.
# 입력층에만 input_dim 을 입력해주고 이후에는 생략 가능하다.
model.add(Dense(8, input_dim = 4, kernel_initializer = 'uniform', activation = 'relu'))
model.add(Dense(6, kernel_initializer = 'uniform', activation = 'relu'))
model.add(Dense(1, kernel_initializer = 'uniform', activation = 'sigmoid'))
위의 코드는 입력값을 4개 받아 1개의 출력값을 내보내는 레이어입니다. 그리고 아래 그림은 이것을 레고블럭으로 표현한 것입니다. 왼쪽 그림은 Dense 레이어 3개를 나타낸 것이고, 오른쪽 그림은 입력부터 출력까지 전체를 나타낸 것입니다.
위의 코드를 사용해서 4개의 입력값을 받아 이진분류를 수행하는 모델을 구현하고, 시각화하면 아래와 같습니다.
from keras.models import Sequential
from keras.layers import Dense
model = Sequential()
model.add(Dense(8, input_dim = 4, kernel_initializer = 'uniform', activation = 'relu'))
model.add(Dense(6, kernel_initializer = 'uniform', activation = 'relu'))
model.add(Dense(1, kernel_initializer = 'uniform', activation = 'sigmoid'))
from IPython.display import SVG
from keras.utils.vis_utils import model_to_dot
SVG(model_to_dot(model, show_shapes=True).create(prog='dot', format='svg'))
이와 같이 케라스에서는 Dense 레이어를 쌓아 입출력 뉴런의 수를 설정하고, 최종 아웃풋을 만드는 모델을 만들 수 있습니다.
Reference
- 블록과 함께 하는 파이썬 딥러닝 케라스 (김태영 저)