딥러닝은 이미지 인식, 자연어 처리, 자율 주행 등 많은 분야에서 활용되고 있다. 현재는 다양한 아키텍처가 발전했지만, 이전에 가장 두드러진 아키텍처로 DNN, CNN, RNN이 있다. 각각 특정한 유형의 데이터와 작업을 처리하도록 설계되었는데, 이번 포스팅에서는 DNN을 python 예제와 함께 살펴보자.
DNN(Deep Neural Network)
DNN은 입력층과 출력층 사이에 여러 개의 은닉층을 가진 인공 신경망이다. "Deep" 이라는 용어는 층(Layer)의 수를 나타내며, 여러 개의 은닉층을 통해 입력 데이터를 처리하여 출력 결과를 생성한다. 이는 기본적인 인공 신경망(ANN)의 확장된 형태로, 더 많은 층과 뉴런을 포함하여 보다 복잡한 패턴과 구조를 학습할 수 있다. 기본적인 구조는 다음과 같다.
- 입력층(Input Layer) : 입력 데이터를 받아들이는 층으로, 데이터의 특징(feature)을 입력으로 받는다.
- 은닉층(Hidden Layer) : 입력층과 출력층 사이에 위치한 층으로, 여러 개의 층으로 구성될 수 있따. 이 층들은 입력 데이터를 처리하고 변환하여 다음 층으로 전달한다.
- 출력층(Output Layer) : 최종 결과를 출력하는 층으로, 분류 문제에서는 클래스의 확률을 출력할 수 있고, 회귀 문제에서는 연속적인 값을 출력할 수 있다.
이 때 여러 개의 층을 통화하면서 각 뉴런은 다음의 두 단계를 거친다.
- 선형 변환(Linear Transformation)
- 입력 데이터 x와 가중치 w를 선형 결합한다.
- 수학적으로는 z = w * x + b로 표현된다. 여기서 b는 편향(bias)
- 편향(bias) : 신경망에서 활성화 함수의 입력값에 더해지는 상수값으로, Neural Network가 더 유연하고 표현력 있는 모델을 만드는 데 활용된다.
- 편향의 역할 : 활성화 함수의 이동(shift), 학습 능력 향상(유연한 결정 경계), 학습 과정 개선(활성화 함수)
- 비선형 활성화 함수(Non-linear Activation Function)
- 선형 변환의 결과에 비선형 활성화 함수를 적용하여 뉴런의 출력을 생성
- 일반적인 활성화 함수로는 ReLU, Sigmoid, tanh 등이 있다.
- 활성화 함수는 모델이 비선형성을 학습할 수 있게 하여 복잡한 데이터 패턴을 포착하도록 한다.
선형 변환은 입력 데이터를 가중치와 편향을 통해 변환하는 수학적 과정이다. 이는 입력 데이터가 뉴런에 의해 처리되는 첫 번째 단계로, 입력 데이터의 가중 합을 계산한다. 이 선형 변환을 통해 입력 데이터가 다음 층의 뉴런으로 전달되기 전에 가중치와 편향에 의해 조정된다.
예를 들어, 입력 데이터 예를 들어, 입력 데이터 x = [x1,x2,x3]와 가중치 w = [w1,w2,w3]가 주어진다고 가정해보자. 각 입력은 해당 가중치와 곱해진 후, 모든 결과가 더해진다. 여기에 편향 b를 더하여 다음과 같은 선형 변환을 수행한다.
z = w1 * x1 + w2 * x2 + w3 * x3 + b
이 z 값은 비선형 활성화 함수에 입력되어 최종 뉴런 출력을 생성한다.
활성화 함수(Activation Function)
python 예제를 살펴보기 전에, 활성화 함수의 종류에 대해 간단하게 정리해보자.

1. Sigmoid
sigmoid 함수는 입력 값을 [0,1] 범위로 압축한다. 이는 출력 값이 확률을 나타내야 하는 이진 분류(Binary Classification) 문제에 자주 사용된다.
장점
- 확률적 해석 : 출력 값이 0과 1 사이에 위치하므로 확률적 해석이 가능하다.
- 연속적이고 미분 가능 : 모든 입력 값에 대해 연속적이고 미분 가능하여 역전파에 유리함
단점
- 기울기 소실(Gradient Vanishing) : 입력 값이 매우 크거나 작은 경우, 기울기가 매우 작아져 학습이 어려워질 수 있음
- 출력 범위 제한 : 출력이 [0,1]로 제한되어 있어, 매우 큰 양수나 음수 값을 효과적으로 처리하지 못함
2. Tanh(Hyperbolic Tangent)
Tanh 함수는 입력 값을 [-1,1] 범위로 압축한다. Sigmoid 함수와 유사하지만 중심이 0이므로 음수 입력 값은 음수 출력을, 양수 입력 값은 양수 출력을 가진다.
장점
- 중심이 0 : 출력 값의 평균이 0에 가까워지므로, 다음 층의 입력이 더 잘 정규화된다.
- 기울기 소실 문제 개선 : Sigmoid 함수에 비해 기울기 소실 문제가 덜 심각하다.
단점
- 기울기 소실(Gradient Vanishing) : Sigmoid에 비해 덜 심각한 것이기, 여전히 기울기 소실 위험은 존재한다. -1과 1에 가까워질수록 기울기가 작아지기 때문이다.
3. ReLU(Rectified Linear Unit)
ReLU는 가장 많이 사용되는 활성화 함수 중 하나로, 입력이 양수인 경우 입력 값을 그대로 출력하고, 음수인 경우에는 0을 출력한다.
장점
- 단순함 : 계산이 매우 간단하여 학습 속도를 빠르게 한다.
- 희소성 : 음수 값을 0으로 변환하여 일부 뉴런을 비활성화 시킴으로써 모델의 희소성을 증가시킨다.
- 기울기 소실 문제 해결 : sigmoid나 tanh 함수에 비해 기울기 소실 문제를 크게 완화한다.
단점
- Dead ReLU 문제 : ReLU 뉴런이 음수 입력 값만 계속 받게 되면, 해당 뉴런은 항상 0을 출력하게 되어 학습되지 않는 문제가 발생한다. 이를 해결하기 위해 Leaky ReLU, Parametric ReLU와 같은 변형된 ReLU 함수가 사용된다.
그렇다면, ReLU는 어떻게 기울기 소실 문제를 완화할까?
- 출력 값의 분포 : ReLU 함수는 음수 입력 값을 0으로, 양수 입력 값을 그대로 출력한다. 이는 ReLU가 0 이상의 값을 출력할 때, 기울기가 항상 1이 되도록 한다. 따라서, 입력 값이 커지더라도 기울기가 0으로 수렴하지 않는다.
- 비선형성 유지 : ReLU는 입력 값의 절반 이상을 0으로 만듦으로써 모델에 비선형성을 추가한다. 이는 신경망이 복잡한 패턴을 학습할 수 있도록 도와준다.
- 희소성(Sparsity): ReLU의 특성으로 인해 뉴런의 절반이 0이 되어 희소성을 증가시킨다. 이는 모델의 일반화 성능을 향상시키고 과적합을 줄일 수 있다.
4. Leaky ReLU(LReLU)
Leaky ReLU는 ReLU의 변형으로, 입력 값이 음수일 때도 작은 기울기를 가지도록 만든 함수다. 이를 통해 ReLU에서 발생할 수 있는 '죽은 ReLU' 문제를 완화할 수 있다.
특징
- 음수 값에 작은 기울기를 부여하여 모든 뉴런이 학습에 기여할 수 있도록 함
- ReLU의 간단함과 계산 효율성을 유지하면서 죽은 뉴런 문제를 완화
- 하지만, 음수 부분의 기울기 값을 적절히 선택하는게 어렵고 극단값에 민감하다는 단점도 존재
5. Maxout
Maxout은 신경망의 각 층에서 여러 선형 함수 중 최대값을 선택하는 방식으로 작동하는 활성화 함수이다. 이는 비선형성을 더 잘 표현할 수 있도록 한다. 기존의 뉴런은 하나의 선형 함수에 활성화 함수를 적용하여 출력을 생성한다. 하지만, Maxout 뉴런은 개별 입력에 대해 여러 선형 함수를 계산하고, 계산된 값 중 최대값을 선택하여 최종 출력으로 사용한다.
특징
- 다양한 비선형성을 학습할 수 있어 더 강력한 표현력을 가짐
- 다중 퍼셉트론(MLP)와 잘 통합되어 성능을 향상시킬 수 있음
- 하지만, 파라미터의 수가 증가하여 모델의 복잡성과 계산 비용이 증가함
6. ELU
ELU는 ReLU와 Leaky ReLU의 단점을 보완하기 위해 고안된 함수로, 입력이 음수일 때도 지수 함수 형태를 가지도록 설계되었다. 이를 통해 신경망이 일정한 기울기를 유지할 수 있다.
특징
- 음수 구간에서의 출력을 일정하게 유지하여 평균 출력을 0에 가깝게 만든다.
- 기울기가 음수 구간에서도 0이 아니므로 Dead 문제를 방지한다.
- 지수 함수 계산이 포함되어 있어 ReLU에 비해 계산 비용이 약간 더 높다는 단점도 존재한다.
7. Softmax

softmax 함수는 다중 클래스 분류 문제에서 자주 사용된다. 개별 클래스에 대한 확률 분포를 출력하며, 모든 출력 값의 합이 1이 되도록 정규화한다. sigmoid가 [0,1]의 범위에서 threshold의 값에 따라 이진 분류를 한다면, softmax는 무한대의 범위를 가진 logit을 [0,1] 범위의 확률로 변환한다.
특징
- 확률적 해석 : 각 클래스에 대한 확률 값을 제공하여 다중 클래스 분류 문제에 적합함
- 출력의 합이 1 : 모든 클래스의 확률 합이 1이 되도록 보장하여 확률 분포를 형성
- 계산 복잡성 : 다른 활성화 함수에 비해 계산이 복잡하여 다중 클래스 분류 문제에서만 사용됨
Python 예제
# Tensorflow 예제
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense
# 더미 데이터 생성
X = np.random.rand(1000, 20) # 1000개의 샘플, 각 샘플당 20개의 특징
y = np.random.randint(2, size=(1000, 1)) # 이진 분류
# DNN 모델 정의
model = Sequential()
model.add(Dense(64, input_dim=20, activation='relu'))
model.add(Dense(64, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
# 모델 컴파일
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# 모델 훈련
model.fit(X, y, epochs=10, batch_size=10)
# 모델 평가
loss, accuracy = model.evaluate(X, y)
print(f'Loss: {loss}, Accuracy: {accuracy}')
# Pytorch 예제
import torch
import torch.nn as nn
import torch.optim as optim
# 더미 데이터 생성
X = torch.randn(1000, 20) # 1000개의 샘플, 각 샘플당 20개의 특징
y = torch.randint(0, 2, (1000, 1)).float() # 이진 분류
# DNN 모델 정의
class DNN(nn.Module):
def __init__(self):
super(DNN, self).__init__()
self.layer1 = nn.Linear(20, 64)
self.layer2 = nn.Linear(64, 64)
self.output = nn.Linear(64, 1)
self.relu = nn.ReLU()
self.sigmoid = nn.Sigmoid()
def forward(self, x):
x = self.relu(self.layer1(x))
x = self.relu(self.layer2(x))
x = self.sigmoid(self.output(x))
return x
model = DNN()
criterion = nn.BCELoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)
# 모델 훈련
for epoch in range(10):
optimizer.zero_grad()
outputs = model(X)
loss = criterion(outputs, y)
loss.backward()
optimizer.step()
print(f'Epoch {epoch+1}, Loss: {loss.item()}')
# 모델 평가
with torch.no_grad():
outputs = model(X)
predicted = (outputs > 0.5).float()
accuracy = (predicted == y).float().mean()
print(f'Accuracy: {accuracy.item()}')
딥러닝에는 여러가지 프레임워크가 있는데, 대표적으로 텐서플로우(Tensorflow)와 파이토치(Pytorch)를 가장 널리 사용한다. Tensorflow는 Keras라는 라이브러리를 활용해 쉽게 모델을 구축할 수 있고, Pytorch는 Python과 매우 유사한 문법을 사용하여 디버깅과 모델 개발이 더 쉽다는 장점이 있다. 위의 두 가지 예제 모두 동일한 데이터와 아키텍처를 표현한 결과이다. 결과는 동일하지만, 어떤 프레임워크를 쓰냐에 따라 코드 구성이 달라진다고 해석하면 된다.
'Data Science' 카테고리의 다른 글
| [API] API의 정의와 원리 (1) | 2025.09.20 |
|---|---|
| [웹크롤링] Tmax 채용공고 분석 (0) | 2024.08.05 |
| [에이블스쿨] 딥러닝이란? (0) | 2024.04.06 |
| [에이블스쿨] SVM (2) | 2024.03.24 |
| [에이블스쿨] 평균과 중심극한정리 (0) | 2024.03.18 |