logo

[딥러닝] 다층 신경망

 

다층 신경망이란?

 

정의 및 필요성

다층 신경망의 정의

다층 신경망(Multi-Layer Perceptron, MLP)은 인공 신경망의 한 유형으로, 하나 이상의 은닉층을 포함한 구조를 갖습니다. 기본적인 신경망, 즉 단일 퍼셉트론에서 한 단계 더 발전한 형태로 볼 수 있습니다. 이러한 구조는 복잡한 데이터 패턴을 학습하고 예측하는 데 있어 단일 퍼셉트론보다 훨씬 뛰어난 성능을 보입니다.

단일 퍼셉트론 대비 다층 신경망의 이점

단일 퍼셉트론은 오직 입력층과 출력층만을 가집니다. 이러한 단순함으로 인해 선형 분리 가능한 문제에 대해서만 해결할 수 있습니다. 반면, 다층 신경망은 하나 혹은 그 이상의 은닉층을 통해 입력 데이터에서 더 복잡한 특징을 추출하고 학습할 수 있습니다. 이로 인해 비선형 문제와 더 복잡한 데이터 패턴을 해결할 수 있는 능력을 갖추게 됩니다.

 

기본 구조

입력층, 은닉층, 출력층의 개념 소개

  • 입력층(Input Layer): 데이터가 신경망에 처음 들어오는 지점입니다. 각 노드는 입력 데이터의 한 특징(feature)을 나타냅니다.
  • 은닉층(Hidden Layer): 여러 개의 층으로 구성될 수 있으며, 각 층은 여러 뉴런(노드)으로 이루어져 있습니다. 은닉층은 입력 데이터에서 높은 수준의 추상화를 진행하여 복잡한 특성을 학습합니다.
  • 출력층(Output Layer): 신경망의 최종 예측을 위한 층입니다. 문제의 성격에 따라 적절한 활성화 함수를 통해 최종 예측 결과를 제공합니다.

각 층의 기능 및 중요성

  • 입력층: 신경망에 데이터를 제공하는 역할을 담당합니다. 입력층의 노드 수는 데이터의 특징 수에 해당합니다.
  • 은닉층: 다층 신경망의 핵심 부분으로, 복잡한 특징을 추출하고 학습하는 역할을 합니다. 은닉층이 여러 개일 경우, 각 층은 점점 더 고수준의 데이터 추상화를 실행합니다.
  • 출력층: 모델이 데이터에 대해 내린 최종 결론인 예측 결과를 제공합니다. 출력층의 노드 수와 활성화 함수는 문제의 유형(회귀, 분류 등)에 따라 결정됩니다.
 

예시 코드: PyTorch를 이용한 다층 신경망

import torch
import torch.nn as nn
import torch.optim as optim

# 간단한 다층 신경망 정의
class SimpleMLP(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleMLP, self).__init__()
        self.layer1 = nn.Linear(input_size, hidden_size)  # 입력층 -> 은닉층
        self.relu = nn.ReLU()  # 활성화 함수
        self.layer2 = nn.Linear(hidden_size, output_size)  # 은닉층 -> 출력층

    def forward(self, x):
        out = self.layer1(x)
        out = self.relu(out)
        out = self.layer2(out)
        return out

# 모델, 손실 함수, 옵티마이저 초기화
input_size = 10  # 예: 입력 특징이 10개인 데이터
hidden_size = 5  # 은닉층의 뉴런(노드) 수
output_size = 2  # 예: 이진 분류 문제

model = SimpleMLP(input_size, hidden_size, output_size)
loss_function = nn.CrossEntropyLoss()  # 분류 문제에 사용되는 손실 함수
optimizer = optim.SGD(model.parameters(), lr=0.01)

# 데이터(가상), 목표값
x = torch.randn(1, input_size)
target = torch.tensor([1])  # 예시 목표값

# 순전파 -> 손실 계산 -> 역전파 -> 매개변수 업데이트
optimizer.zero_grad()  # 기울기 초기화
output = model(x)
loss = loss_function(output, target)
loss.backward()
optimizer.step()

print('손실:', loss.item())

이 코드는 PyTorch를 이용하여 간단한 다층 신경망 모델을 생성하고, 무작위 데이터로 학습 과정을 시뮬레이션하는 예시를 보여줍니다. 모델은 입력층, 하나의 은닉층, 그리고 출력층을 포함합니다. 손실 함수와 옵티마이저는 학습 과정을 제어하기 위해 사용됩니다.


 

다층 신경망의 작동 원리

 

순방향 전파 (Feedforward)

다층 신경망에서의 순방향 전파는 데이터가 입력층에서 시작하여 출력층까지 이동하는 과정을 의미합니다. 이 과정은 모든 입력 데이터가 가중치와 편향을 통해 변환되며, 최종적으로 모델이 예측을 생성하는 과정입니다.

순방향 전파에서는 먼저 입력층에 데이터 XX가 제공됩니다. 이 데이터는 다음 층으로 전달되기 전에 각 뉴런의 가중치 WW와 편향 bb을 이용하여 변환됩니다. 변환된 데이터는 Z=WX+bZ = WX + b의 식을 통해 계산됩니다. 여기서 ZZ는 가중치가 적용된 입력 데이터의 결과입니다. 이후, 결과 ZZ는 활성화 함수를 거쳐 다음 층으로 전달됩니다.

PyTorch를 사용한 간단한 예제 코드는 다음과 같습니다.

import torch
import torch.nn as nn

# 가정: 입력 차원이 10, 출력 차원이 2인 단일 은닉층 신경망
input_dim = 10
hidden_dim = 5
output_dim = 2

# 단일 은닉층 신경망 정의
class SimpleNN(nn.Module):
    def __init__(self):
        super(SimpleNN, self).__init__()
        self.layer1 = nn.Linear(input_dim, hidden_dim)
        self.relu = nn.ReLU()
        self.layer2 = nn.Linear(hidden_dim, output_dim)

    def forward(self, x):
        x = self.layer1(x)
        x = self.relu(x)
        x = self.layer2(x)
        return x

# 모델 및 입력 데이터 생성
model = SimpleNN()
input_data = torch.rand(1, input_dim)  # 배치 크기 1, 차원 10의 입력 데이터

# 순방향 전파 실행
output = model(input_data)

위 코드에서 SimpleNN은 입력층, 하나의 은닉층, 그리고 출력층을 갖는 간단한 다층 신경망입니다. 순방향 전파는 forward 메서드 내에서 정의되며, 이 과정을 통해 입력 데이터는 최종 출력으로 변환됩니다.

 

활성화 함수의 역할

활성화 함수는 신경망의 비선형 특성을 도입하는 데 중요한 역할을 합니다. 만약 활성화 함수가 없다면, 신경망은 아무리 많은 층을 쌓더라도 결국 선형 함수의 조합으로 남게 되어 복잡한 패턴을 학습하는 데 한계가 있습니다.

시그모이드 함수는 가장 널리 알려진 활성화 함수 중 하나로, 출력값을 0과 1 사이로 압축하는 특징이 있습니다. 시그모이드 함수는 다음과 같은 수식으로 표현됩니다:

S(x)=11+ex S(x) = \frac{1}{1+e^{-x}}

시그모이드 함수는 초기 신경망에서 출력층에 주로 사용되었습니다. 그러나 그라디언트 소실 문제가 있어 현재는 ReLU와 같은 다른 활성화 함수가 은닉층에서 선호됩니다.

PyTorch 코드로는 시그모이드 활성화 함수를 다음과 같이 적용할 수 있습니다.

import torch

# 시그모이드 활성화 함수 적용
activation = torch.nn.Sigmoid()
input_tensor = torch.tensor([-1.0, 0.0, 1.0, 2.0])
output_tensor = activation(input_tensor)

print(output_tensor)

활성화 함수를 적용함으로써, 신경망은 비선형 문제를 해결할 수 있는 능력을 갖게 됩니다.


 

학습 과정

 

손실 함수

다층 신경망의 학습 과정에서 손실 함수는 매우 중요한 역할을 합니다. 손실 함수는 실제 값과 다층 신경망이 예측한 값 사이의 차이, 즉 '손실'을 계산하는 데 사용됩니다. 이 차이를 최소화함으로써 모델의 예측 능력을 향상시킵니다. 다양한 종류의 손실 함수가 있지만, 여기에서는 분류 문제에 주로 사용되는 교차 엔트로피(cross-entropy)에 대해 설명합니다.

교차 엔트로피 손실 함수는 분류 문제에서 실제 분포와 예측 분포 사이의 차이를 측정합니다. 이는 모델이 예측한 확률 분포와 실제 데이터의 분포 사이의 '거리'를 나타냅니다.

import torch
import torch.nn as nn

# 예시: 이진 분류 문제에 대한 교차 엔트로피 손실 함수
loss_function = nn.CrossEntropyLoss()

이 손실 함수는 학습 과정에서 네트워크의 가중치를 조정하는 데 필요한 정보를 제공합니다.

 

경사 하강법

경사 하강법은 손실 함수를 최소화하기 위한 핵심 기법입니다. 이 방법은 손실 함수의 기울기(그래디언트)를 계산하여, 해당 기울기가 감소하는 방향으로 모델의 가중치를 조정합니다.

optimizer = torch.optim.SGD(model.parameters(), lr=0.01)

여기서 lr은 학습 속도(learning rate)를 나타냅니다. 학습 속도는 가중치가 업데이트되는 정도를 결정합니다.

경사 하강법의 다양한 변형들은 다층 신경망의 학습 속도와 안정성을 향상시키기 위해 개발되었습니다. 예를 들어, 모멘텀(Momentum), 아담(Adam), RMSprop 등의 방법이 있으며, 이들은 학습률을 동적으로 조정하거나 이전 그래디언트 값을 일정 부분 유지함으로써 학습 과정을 보다 안정적이고 빠르게 만듭니다.

optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
 

역전파 (Backpropagation)

역전파는 다층 신경망에서 가중치를 조정하는 효율적인 방법입니다. 이 기술은 출력층에서 입력층으로 거슬러 올라가며, 각 층에서의 가중치를 손실 함수의 그래디언트에 따라 조정합니다.

역전파는 다음 단계로 진행됩니다:

  1. 네트워크를 통해 입력을 전파하고, 출력을 생성합니다.
  2. 출력과 실제 값 사이의 손실을 계산합니다.
  3. 손실 함수의 그래디언트를 계산합니다.
  4. 계산된 그래디언트를 사용하여 네트워크의 가중치를 업데이트합니다.

PyTorch와 같은 현대 딥러닝 프레임워크는 자동 미분(automatic differentiation) 기능을 제공하여, 이러한 역전파 과정을 간소화합니다.

# 손실 계산
loss = loss_function(predictions, true_values)

# 기존 그래디언트를 초기화
optimizer.zero_grad()

# 손실 함수에 대한 가중치의 그래디언트 계산
loss.backward()

# 가중치 업데이트
optimizer.step()

단일 반복 과정에서 위 코드를 실행하여, 네트워크 가중치를 업데이트합니다. 이 과정은 데이터셋에 대해 여러 번 반복되며, 각 반복을 통해 모델의 성능이 점차적으로 향상됩니다.

Previous
딥러닝 프레임워크 소개