R) DL - Multi Layer Model-01

R) DL - Multi Layer Model-01

CRAN RStudio mirror downloads
단층 퍼셉트론을 넘어서서 은닉층(hidden layer)가 있는 다층 구조 신경망을 만들어보자.

개요

구조

여기서 구현할 내용은 정확하게는 입력층, 은닉층, 출력층 3개로 나뉘어지는 신경망이다. 경우에 따라 입력층(input layer)는 인정하지 않고 무시하는 경우도 있다. 출력층(output layer)를 통해 값을 출력하며 일반적으로 신경망 목적에 따라 노드 개수를 결정한다. 은닉층(hidden layer)는 밖에서 바로 관측이 되지 않는 층이며 값 변화를 보기 어렵다.
신경망 구조


은닉층

은닉층은 노드와 층수가 증가함에 따라 학습 데이터의 특징을 보다 잘 파악할 수 있도록 해준다. 이 은닉층의 개수가 여러 개인 신경망으로 학습하는 것을 딥러닝(DL, Deep Learning) 이라고 한다.


손실 함수

손실 함수(Loss Function)는 오차 함수(Error Function), 비용 함수(Cost Function) 라고도 한다. 학습을 통해 최적의 매개변수를 결정하기위한 지표로 사용하는데 기본적으로 신경망은 오차를 가장 적게 만드는 것이 목표이다 그래서 이 값이 작게 나오도록 신경망을 최적화 시킨다. 다양한 손실함수가 있으나 MSE와 CEE가 보편적으로 사용된다.


데이터 준비

학습용 데이터를 준비하는 과정에서 배치 크기와 입출력 노드에 맞춰서 임의의 수를 생성한다. 여기서 하이퍼파라미터 설정이 살짝 들어와있는데 사전에 준비된 데이터가 아니라 미리 신경망 구조를 정해두고 만드는 것도 한몫 한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
library("torch")

batch_size = 64
D_in = 1000
D_out = 10

torch_manual_seed(123)
x = torch_randn(batch_size, D_in, device = device)
y = torch_randn(batch_size, D_out, device = device)
dim(x)
## [1] 64 1000

x[1:3, 1:3]
## torch_tensor
## 0.3374 -0.1778 -0.3035
## 0.2573 0.6937 0.4207
## 2.5754 -1.3320 0.2282
## [ CPUFloatType{3,3} ]

하이퍼파라미터 설정

사용할 장치(cpu 또는 cuda), 배치 크기 및 신경망 노드 개수, 손실함수(loss function, MSE 사용), 학습률(learning rate)을 설정한다. 배치 크기와 노드 개수는 앞에서 정의하긴 했지만 하이퍼파라미터를 한 곳에 모아놓기 위해 다시 한 번 언급하였다. 그리고 학습률의 경우 1e-4라고 되어있는데 $10^{-4}$와 같고 1/10000 이다.

1
2
3
4
5
6
7
8
9
10
device = torch_device("cpu") # cuda

batch_size = 64
D_in = 1000
H = 100
D_out = 10

loss_fn = nnf_mse_loss # MSE

learning_rate = 1e-4 # 1/10000

신경망 구조 정의

신경망을 적층 할 때는 각 층의 입력과 출력을 잘 맞춰주어야 한다. 신경망 학습에서는 이 부분에서 실수가 잦기 때문에 되도록이면 같은 숫자를 받아야 하는 곳에는 같은 객체로 그 숫자를 관리할 수 있도록 하자. udf_str() 함수의 경우 적층할 때 객체지향형이 아니라 파이프라인 연산자(%>%)를 활용하여 절차지향형으로 기술하여 보다 이해하기 쉽게 코드를 작성하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
udf_init = function(D_in, H, D_out) {
self$layer_01 = nn_linear(in_features = D_in, out_features = H)
self$layer_02 = nn_linear(in_features = H, out_features = D_out)
}

udf_str = function(input){
input %>%
self$layer_01() %>%
nnf_relu() %>%
self$layer_02()
}

torch_manual_seed(123)
net_layer_02 = nn_module(classname = "two_layer_net",
initialize = udf_init,
forward = udf_str)
model = net_layer_02(D_in, H, D_out)

학습 및 평가

최적화 알고리즘은 SGD(Stochastic Gradient Descent, 확률적 경사 하강법)을 사용하고 중간중간 손실 출력은 if 함수를 통해 100의 배수에만 출력되도록 하였다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
optimizer = optim_sgd(model$parameters, lr = learning_rate)
for(n_step in 1:500){
y_pred = model(x) # 예측값 생산
loss = loss_fn(y_pred, y) # 손실 계산

if(n_step %% 100 == 0)
cat("Step:", n_step, ":", as.numeric(loss), "\n")

optimizer$zero_grad()
loss$backward() # 역전파
optimizer$step() # 가중치 갱신
}
## Step: 100 : 1.070939
## Step: 200 : 1.057227
## Step: 300 : 1.043858
## Step: 400 : 1.030812
## Step: 500 : 1.018066
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×