인공 신경망(ANN)
생물학적 신경망을 모방한 컴퓨팅 시스템
입력층(Input Layer), 은닉층(Hidden Layer), 출력층(Output Layer)으로 구성
각 층은 뉴런(Neuron)으로 이루어져 있으며, 가중치(Weight)와 활성화 함수(Activation Function)를 사용해 데이터를 처리
- 입력층 : 입력 데이터를 받아들이는 층
입력 뉴런 수는 입력 데이터의 특징(Feature) 수와 동일 - 은닉층 : 입력 데이터를 처리하고 특징을 추출하는 층
뉴런 수와 층 수에 따라 모델 성능이 결정됨 - 출력층 : 최종 예측 값을 출력하는 층
뉴런 수는 예측하려는 클래스 개수 또는 회귀 문제의 출력 차원과 동일
동작 방식
- 순전파 (Foward Propagation)
입력 데이터 → 각 층의 뉴런 활성화 → 최종 출력 값 계산
각 뉴런은 가중치(Weight)를 적용하고, 바이어스(Bias)를 더한 후 활성화 함수로 출력 결정 - 손실 계산 (Loss Calculation)
모델이 예측한 값과 실제 값의 차이를 손실 함수(Loss Function)로 계산 - 역전파 (Backpropagation) 및 가중치 업데이트
출력층에서 입력층 방향으로 손실 함수의 기울기(Gradient)를 계산
경사 하강법(Gradient Descent) 등을 활용해 가중치를 업데이트
출력 레이어의 유형과 활용
출력층은 문제 유형에 따라 구성 방식이 다름
회귀 문제(Regression)
출력층 뉴런 수 : 예측하려는 연속값 차원과 동일
활성화 함수 : 선형 함수(Linear Function) 사용
이진 분류(Binary Classification)
출력층 뉴런 수 : 1개
활성화 함수 : 시그모이드(Sigmoid) 함수 사용
예측 값 : 0~1 사이의 확률값, 0.5 기준으로 분류
다중 클래스 분류 (Multi-Class Classification)
출력층 뉴런 수 : 예측하려는 클래스 수와 동일
활성화 함수 : 소프트맥스(Softmax) 함수 사용
예측 값 : 각 클래스에 대한 확률값 출력
인공 신경망 모델 구현 (PyTorch)
PyTorch 및 라이브러리 임포트
import torch # PyTorch 핵심 라이브러리 (텐서 연산, 모델 구축 및 학습 지원)
import torch.nn as nn # nueral network 모듈 (레이어, 활성화 함수 등 제공)
import torch.optim as optim # 최적화 알고리즘 (SGD, Adam 등)
import torchvision # 컴퓨터 비전 관련 데이터셋 및 모델 제공 (MNIST, CIFAR-10 등 포함)
import torchvision.transforms as transforms # 이미지 변환 및 전처리 도구 (정규화, 텐서 변환 등)
데이터셋 로드 및 전처리
# 이미지 변환 설정 (데이터 전처리)
transform = transforms.Compose([
transforms.ToTensor(), # 이미지를 PyTorch 텐서로 변환 (0~255 → 0~1 정규화)
transforms.Normalize((0.5), (0.5)) # 평균 0.5, 표준편차 0.5로 정규화
])
# MNIST 학습 데이터셋 로드 (훈련 데이터: 60,000개)
trainset = torchvision.datasets.MNIST(
root='./data', # 데이터를 저장할 경로
train=True, # 학습 데이터셋 로드
download=True, # 데이터가 없으면 다운로드
transform=transform # 전처리 적용
)
# 데이터 로더 생성 (배치 크기: 64 - 1개의 배치에 64개의 샘플 포함, shuffle=True: 매 Epoch마다 데이터를 섞음 (훈련 성능 향상) )
trainloader = torch.utils.data.DataLoader(
trainset, batch_size=64,shuffle=True
)
# MNIST 테스트 데이터셋 로드 (테스트 데이터: 10,000개)
testset = torchvision.datasets.MNIST(
root:'./data',
train=False, #테스트 데이터셋 로드
download=True,
transform=transform
)
# 테스트 데이터 로더 생성 - shuffle=False(테스트 데이터는 섞지 않음)
testloader = torch.utils.data.DataLoader(
testset, batch_size=64, shuffle=False
)
# 데이터셋 크기 확인
print(f"Train data: {len(trainset)}, Test data: {len(testset)}")
"""
Train data: 60000, Test data: 10000
"""
# 배치 데이터 확인
# 데이터 로더에서 첫 번째 배치 가져오기
dataiter = iter(testloader) # 테스트 데이터 로더에서 반복자 생성
images, labels = next(dataiter) # 첫 번째 배치에서 이미지와 레이블 가져오기
# 배치 데이터 형태 출력
print(f"Test batch shape: {images.shape}") # 이미지 텐서 크기 확인
print(f"Test labels: {labels}") # 배치 내 레이블 확인
"""
Test batch shape: torch.Size([64, 1, 28, 28])
Test labels: tensor([7, 2, 1, 0, 4, 1, 4, 9, 5, 9, 0, 6, 9, 0, 1, 5, 9, 7, 3, 4, 9, 6, 6, 5,
4, 0, 7, 4, 0, 1, 3, 1, 3, 4, 7, 2, 7, 1, 2, 1, 1, 7, 4, 2, 3, 5, 1, 2,
4, 4, 6, 3, 5, 5, 6, 0, 4, 1, 9, 5, 7, 8, 9, 3])
"""
배치 크기: 64 → 한 번에 64개의 샘플 (배치 크기)
채널 수: 1 → 흑백 이미지(Grayscale)
이미지 크기: 28 x 28 → MNIST 손글씨 이미지 크기
ANN 모델 정의
# torch.nn.Module : 모든 신경망 모듈의 기본 클래스, 사용자 정의 신경망은 이 클래스의 상속을 받음
# nn.Linear : 선형 변환을 적용하는 완전 연결(fully connected)레이어 정의
class SimpleANN(nn.Module):
def __init__(self):
super(SimpleANN, self).__init__()
# nn.Linear(in_features, out_features) : 완전연결(fully connected) 레이어 정의
self.fc1 = nn.Linear(28 * 28, 128) # 입력층 → 은닉층
self.fc2 = nn.Linear(128, 64) # 은닉층 → 은닉층
self.fc3 = nn.Linear(64, 10) # 은닉층 → 출력층
def forward(self, x):
x = x.view(-1, 28 * 28) # 1차원 변환(입력 이미지를 1차원 벡터 28 x 28 → 784)로 변환
x = torch.relu(self.fc1(x)) # ReLU 활성화 함수 적용
x = torch.relu(self.fc2(x))
x = self.fc3(x) # 최종 출력 (Softmax 미적용, Loss 함수 내부에서 적용)
return x
모델 학습
# 모델 초기화
model = SimpleANN()
# 손실 함수 및 최적화 알고리즘 설정
criterion = nn.CrossEntropyLoss() # 다중 분류 손실 함수 : 예측 값과 실제 값 사이의 교차 엔트로피 손실 계산
optimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9) # 확률적 경사 하강법(Stochastic Gradient Descnet)최적화 알고리즘 정의, lr=학습률, momentum=모멘텀 값
# 모델 학습 (10 Epoch)
for epoch in range(10): # 10 에포크 동안 학습
running_loss = 0.0
for i, (inputs, labels) in enumerate(trainloader):
# 기울기 초기화 - 이전 단계에서 계산된 기울기 초기화
optimizer.zero_grad()
# 순전파 + 역전파 + 최적화
outputs = model(inputs) # 순전파
loss = criterion(outputs, labels) # 손실 계산
loss.backward() # 역전파를 통해 기울기 계산
optimizer.step() # 계산된 기울기를 바탕으로 가중치 업데이트
# 손실 출력
running_loss += loss.item()
if i % 100 == 99: # 100 mini-batch마다 출력
print(f'[Epoch {epoch + 1}, Batch {i + 1}] Loss: {running_loss / 100:.3f}')
running_loss = 0.0
print('Training Finished')
"""
[Epoch 1, Batch 100] Loss: 1.405
[Epoch 1, Batch 200] Loss: 0.512
[Epoch 1, Batch 300] Loss: 0.386
[Epoch 1, Batch 400] Loss: 0.346
[Epoch 1, Batch 500] Loss: 0.302
[Epoch 1, Batch 600] Loss: 0.279
[Epoch 1, Batch 700] Loss: 0.287
[Epoch 1, Batch 800] Loss: 0.241
[Epoch 1, Batch 900] Loss: 0.233
[Epoch 2, Batch 100] Loss: 0.200
[Epoch 2, Batch 200] Loss: 0.193
[Epoch 2, Batch 300] Loss: 0.188
[Epoch 2, Batch 400] Loss: 0.179
[Epoch 2, Batch 500] Loss: 0.170
[Epoch 2, Batch 600] Loss: 0.175
[Epoch 2, Batch 700] Loss: 0.165
[Epoch 2, Batch 800] Loss: 0.160
[Epoch 2, Batch 900] Loss: 0.163
[Epoch 3, Batch 100] Loss: 0.140
[Epoch 3, Batch 200] Loss: 0.157
[Epoch 3, Batch 300] Loss: 0.127
[Epoch 3, Batch 400] Loss: 0.140
[Epoch 3, Batch 500] Loss: 0.128
[Epoch 3, Batch 600] Loss: 0.116
[Epoch 3, Batch 700] Loss: 0.122
[Epoch 3, Batch 800] Loss: 0.120
[Epoch 3, Batch 900] Loss: 0.119
[Epoch 4, Batch 100] Loss: 0.112
[Epoch 4, Batch 200] Loss: 0.109
[Epoch 4, Batch 300] Loss: 0.109
[Epoch 4, Batch 400] Loss: 0.098
[Epoch 4, Batch 500] Loss: 0.094
[Epoch 4, Batch 600] Loss: 0.104
[Epoch 4, Batch 700] Loss: 0.104
[Epoch 4, Batch 800] Loss: 0.097
[Epoch 4, Batch 900] Loss: 0.101
[Epoch 5, Batch 100] Loss: 0.087
[Epoch 5, Batch 200] Loss: 0.082
[Epoch 5, Batch 300] Loss: 0.091
[Epoch 5, Batch 400] Loss: 0.090
[Epoch 5, Batch 500] Loss: 0.086
[Epoch 5, Batch 600] Loss: 0.099
[Epoch 5, Batch 700] Loss: 0.090
[Epoch 5, Batch 800] Loss: 0.097
[Epoch 5, Batch 900] Loss: 0.072
[Epoch 6, Batch 100] Loss: 0.076
[Epoch 6, Batch 200] Loss: 0.085
[Epoch 6, Batch 300] Loss: 0.071
[Epoch 6, Batch 400] Loss: 0.072
[Epoch 6, Batch 500] Loss: 0.078
[Epoch 6, Batch 600] Loss: 0.086
[Epoch 6, Batch 700] Loss: 0.076
[Epoch 6, Batch 800] Loss: 0.082
[Epoch 6, Batch 900] Loss: 0.063
[Epoch 7, Batch 100] Loss: 0.061
[Epoch 7, Batch 200] Loss: 0.057
[Epoch 7, Batch 300] Loss: 0.065
[Epoch 7, Batch 400] Loss: 0.062
[Epoch 7, Batch 500] Loss: 0.070
[Epoch 7, Batch 600] Loss: 0.065
[Epoch 7, Batch 700] Loss: 0.071
[Epoch 7, Batch 800] Loss: 0.067
[Epoch 7, Batch 900] Loss: 0.070
[Epoch 8, Batch 100] Loss: 0.063
[Epoch 8, Batch 200] Loss: 0.060
[Epoch 8, Batch 300] Loss: 0.050
[Epoch 8, Batch 400] Loss: 0.053
[Epoch 8, Batch 500] Loss: 0.059
[Epoch 8, Batch 600] Loss: 0.065
[Epoch 8, Batch 700] Loss: 0.057
[Epoch 8, Batch 800] Loss: 0.058
[Epoch 8, Batch 900] Loss: 0.060
[Epoch 9, Batch 100] Loss: 0.051
[Epoch 9, Batch 200] Loss: 0.049
[Epoch 9, Batch 300] Loss: 0.054
[Epoch 9, Batch 400] Loss: 0.057
[Epoch 9, Batch 500] Loss: 0.052
[Epoch 9, Batch 600] Loss: 0.047
[Epoch 9, Batch 700] Loss: 0.053
[Epoch 9, Batch 800] Loss: 0.054
[Epoch 9, Batch 900] Loss: 0.053
[Epoch 10, Batch 100] Loss: 0.045
[Epoch 10, Batch 200] Loss: 0.045
[Epoch 10, Batch 300] Loss: 0.049
[Epoch 10, Batch 400] Loss: 0.046
[Epoch 10, Batch 500] Loss: 0.053
[Epoch 10, Batch 600] Loss: 0.053
[Epoch 10, Batch 700] Loss: 0.055
[Epoch 10, Batch 800] Loss: 0.045
[Epoch 10, Batch 900] Loss: 0.054
Training Finished
"""
모델 평가
correct = 0
total = 0
with torch.no_grad(): # 기울기 계산 비활성화 - 평가 단계에서는 기울기 계산이 불필요하므로 비활성화하여 메모리 절약
for data in testloader:
images, labels = data
outputs = model(images)
_, predicted = torch.max(outputs, 1) # 가장 높은 확률을 가진 클래스 선택 - 최댓값이 있는 인덱스를 예측 값으로 사용
total += labels.size(0) # 배치 크기 반환
correct += (predicted == labels).sum().item() # 예측 값과 실제 값이 일치하는 샘플 수 계산
accuracy = 100 * correct / total # 정확도(Accuracy) = (정답 개수 / 전체 개수) * 100
print(f'Accuracy on Test Data: {accuracy:.2f}%')
"""
Accuracy on Test Data: 97.45%
"""
'⊢ DeepLearning' 카테고리의 다른 글
순환 신경망(Recrurrent Neural Network, RNN) (0) | 2025.03.20 |
---|---|
합성곱 신경망(Convolutional Neural Network, CNN) (5) | 2025.03.20 |
딥러닝 실습 환경 구축 (0) | 2025.03.18 |
신경망의 기본 원리 - 퍼셉트론과 다층 퍼셉트론 (0) | 2025.03.18 |
Deep Learning (1) | 2025.03.18 |