딥러닝 모델 유형(3) - 인공신경망
딥러닝 구성 요소
#가중치 (w)
가중합 (전달함수)
각 노드에서 들어오는 신호에 가중치를 곱해서 다음 노드로 전달되는데, 이 값들을 모두 더한 합계를 말하며 이것을 모두 활성화 함수로 보낸다.
가중합 공식
#소프트맥스 함수
소프트맥스(softmax) 함수는 입력 값을 0~1 사이에 출력되도록 정규화하여 출력 값들의 총합이 항상 1이 되도록 함
보통 출력 노드의 활성화 함수로 사용하게 됨
소프트맥수 함수 수식
** exp(x)(앞의 식에서는 exp(ak)와 exp(ai)를 의미 지수함수)
n = 출력층의 뉴런 개수
yk = k번째 출력
ak = 입력신호의 지수함수
렐루함수(은닉층 활성함수)와 소프트맥스 함수(출력층 활성함수)를 파이토치에서 구현해보기
class Net(torch.nn.Module):
def__init__(self, n_feature, n_hidden, n_output):
supper(Net, self).__init__()
self.hidden = torch.nn.Linear(n_feature, n_hidden) #------ 은닉층 노드 1단
self.relu = torch.nn.ReLu(inplace=True) #렐루 활성화함수로 건내주기
self.out = torch.nn.Linear(n_hidden, n_output) #------ 출력층
self.softmax = torch.nn.Softmax(dim=n_output) #소프트맥수 출력층 활성화 함수
def forward(self, x):
x = self.hidden(x)
x = self.relu(x) #------ 은닉층을 위한 렐루 활성화 함수
x = self.out(x)
x = self.softmax(x) #------ 출력층을 위한 소프트맥스 활성화 함수
return x
** 경사하강법
학습률(learning rate)과 손실 함수의 순간 기울기를 이용하여 가중치를 업데이트하는 방법
즉, 미분의 기울기를 이용하여 오차를 비교하고 최소화하는 방향으로 이동시키는 방법이라고 볼 수 있음
# 손실함수
학습을 통해 얻은 데이터의 추정치가 실제 데이터와 얼마나 차이가 나는지 평가하는 지표
#평균 제곱 오차
import torch
loss_fn = torch.nn.MSELoss(reduction = 'sum')
y_pred = model(x)
loss = loss_fn(y_pred , y) #손실함수 적용하기(신경망이 추정한 y값(train), 정답레이블 순으로)
크로스 엔트로피 오차
분류(classification) 문제에서 사용하는 손실함수
분류 문제에서는 데이터의 출력을 0과 1로 구분하기 위해 시그모이드 함수를 사용하는데, 시그모이드 함수에 포함된 자연 상수 e 때문에 평균 제곱 오차를 적용하면 매끄럽지 못한 그래프(울퉁불퉁한 그래프)가 출력됩니다. 따라서 크로스 엔트로피 손실 함수를 사용하는데, 이 손실 함수를 적용할 경우 경사 하강법 과정에서 학습이 지역 최소점에서 멈출 수 있습니다. 이것을 방지하고자 자연 상수 e에 반대되는 자연 로그를 모델의 출력 값에 취합니다.
구현 코드
loss = nn.CrossEntropyLoss()
input = torch.randn(5, 6, requires_grad=True) #------ torch.randn은 평균이 0이고 표준편차가 1인 가우시안 정규분포를 이용하여 숫자를 생성
target = torch.empty(3, dtype=torch.long).random_(5) #------ torch.empty는 dtype torch.float32의 랜덤한 값으로 채워진 텐서를 반환
output = loss(input, target)
output.backward()
딥러닝학습 단계(순전파 -> 역전파로 진행됨)
1. 순전파
네트워크에 훈련 데이터가 들어올 때 발생하며, 데이터를 기반으로 예측 값을 계산하기 위해 전체 신경망을 교차해 지나간다.
즉, 모든 뉴런이 이전 층의 뉴런에서 수신한 정보에 변환(가중합 및 활성화 함수)을 적용하여 다음 층(은닉층)의 뉴런으로 전송하는 방식이며, 마지막으로 네트워크를 통해 입력 데이터를 전달하고 데이터가 모든 층을 통과하고 모든 뉴런이 계산을 완료하면 그 예측 값은 최종 층(출력층)에 도달하게 된다.
2. 역전파
손실 함수로 네트워크의 예측 값과 실제 값의 차이(손실, 오차)를 추정함
손실 함수 비용이 0에 가깝도록 하기 위해 모델이 훈련을 반복하면서 가중치를 조정합니다. 손실(오차)이 계산되면 그 정보는 역으로 전파(출력층 → 은닉층 → 입력층)되는 과정을 거치는 것
예측 값과 실제 값 차이를 각 뉴런의 가중치로 미분한 후 기존 가중치 값에서 뺍니다. 이 과정을 출력층 → 은닉층 → 입력층 순서로 모든 뉴런에 대해 진행하여 계산된 각 뉴런 결과를 또다시 순전파의 가중치 값으로 사용한다.
#은닉층 많을수록 발생하는 문제점(그냥 인공신경망을 만들었을 때의 문제점이라고 하자)
과적합(over-fitting)
훈련 데이터를 과하게 학습했기 때문에 예측 값과 실제 값 차이인 오차가 감소하지만, 검증 데이터에 대해서는 오차가 증가하는 것 = 너무 많이 학습하여 오히려 적정 적합에 비하여 오차값이 더 발생하는 것을 의미함
** 과적합을 해결하는 방식 : 드롭아웃 (dropout)
학습 과정 중 임의로 일부 노드들을 학습에서 제외시키는 것
드롭아웃 모델에 적용하기
class DropoutModel(torch.nn.Module):
def__init__(self):
super(DropoutModel, self).__init__()
self.layer1 = torch.nn.Linear(794, 1200) #은닉층 노드1층
self.dropout1 = torch.nn.Dropout(0.5) #------ 50%의 노드를 무작위로 선택하여 사용하지 않는다.
self.layer2 = torch.nn.Linear(1200, 1200)
self.dropout2 = torch.nn.Dropout(0.5)
self.layer3 = torch.nn.Linear(1200, 10)
def forward(self, x):
x = F.relu(self.layer1(x))
x = self.dropout1(x)
x = F.relu(self.layer2(x))
x = self.dropout2(x)
return self.layer3(x)
기울기 소멸