-
Notifications
You must be signed in to change notification settings - Fork 1
temp
Jaehwan edited this page May 16, 2020
·
1 revision
이 글은 활성화 함수인 sigmoid(), softmax(), Relu()의 순전파, 역전파를 제외한 모든 것을 구현하는 모든 코드를 가지고 있다. 이 코드를 다 이해한다면, 역전파에 대한 기초적인 내용은 알게 되었다고 해도 무방하다. 우선 우리가 사용할 함수들의 코드를 가지고 있는 것을 가져온다.
source("./functions.R")
source("./utils.R")
source("./optimizer.R")MNIST 자료를 가져오는 방법에 대한 내용은 Mnist 손글씨 데이터 읽어오는 패키지 소개을 참고한다. 자료를 가져오는 코드는 아래와 같다. 아래 코드에 대한 소개는 다음을 참고한다.
# install.packages("dslabs") 이미 설치한 것이 있으면 생략
library(dslabs)
mnist_data <- get_data()
x_train_normalize <- mnist_data$x_train
x_test_normalize <- mnist_data$x_test
t_train_onehotlabel <- making_one_hot_label(mnist_data$t_train,60000, 10)
t_test_onehotlabel <- making_one_hot_label(mnist_data$t_test,10000, 10)이제 본격적으로 우리가 학습시킬 네트웍을 만든다.
TwoLayerNet <- function(input_size, hidden_size, output_size, weight_init_std = 0.01) {
W1 <- weight_init_std*matrix(rnorm(n = input_size*hidden_size), nrow = input_size, ncol = hidden_size)
b1 <- matrix(rep(0,hidden_size),nrow=1,ncol=hidden_size)
W2 <- weight_init_std*matrix(rnorm(n = hidden_size*output_size), nrow = hidden_size, ncol = output_size)
b2 <- matrix(rep(0,output_size),nrow=1,ncol=output_size)
return (list(W1 = W1, b1 = b1, W2 = W2, b2 = b2))
}앞에서 만든 네트웍을 학습시킬 모델을 만든다. 이 함수를 다 따로 만든 이유는 우선 model.forward()은 예측을 하기 위해 필요하다. loss()은 당연히 손실값을 알아보기 위해서 필요하다.
model.forward <- function(network, x){
Affine_1 <- Affine.forward(network$W1, network$b1, x)
Relu_1 <- Relu.forward(Affine_1$out)
Affine_2 <- Affine.forward(network$W2, network$b2, Relu_1$out)
return(list(x = Affine_2$out, Affine_1.forward = Affine_1, Affine_2.forward = Affine_2, Relu_1.forward = Relu_1))
}
loss <- function(model.forward, network, x, t){
temp <- model.forward(network, x)
y <- temp$x
last_layer.forward <- SoftmaxWithLoss.forward(y, t)
return(list(loss = last_layer.forward$loss, softmax = last_layer.forward, predict = temp))
}
gradient <- function(model.forward, network, x, t) {
# 순전파
temp <- loss(model.forward, network, x, t)
# 역전파
dout <- 1
last.backward <- SoftmaxWithLoss.backward(temp$softmax, dout)
Affine_2.backward <- Affine.backward(temp$predict$Affine_2.forward, dout = last.backward$dx)
Relu_1.backward <- Relu.backward(temp$predict$Relu_1.forward, dout = Affine_2.backward$dx)
Affine_1.backward <- Affine.backward(temp$predict$Affine_1.forward, dout = Relu_1.backward$dx)
grads <- list(W1 = Affine_1.backward$dW, b1 = Affine_1.backward$db, W2 = Affine_2.backward$dW, b2 = Affine_2.backward$db)
return(grads)
}지금까지 만든 것을 테스트해보자.
train_size <- dim(x_train_normalize)[1]
batch_size <- 100
train_loss_list <- data.frame(lossvalue = 0)
train_acc_list <- data.frame(train_acc = 0)
test_acc_list <- data.frame(test_acc = 0)
iter_per_epoch <- max(train_size / batch_size)
<<<<<<< HEAD
temp_TwoLayerNet <- TwoLayerNet(input_size = 784, hidden_size = 50, output_size = 10)
grads <- gradient(model.forward=model.forward, network = temp_TwoLayerNet, x=x_train_normalize[1:batch_mask,], t= t_train_onehotlabel[1:batch_mask,])
loss_value <- loss(model.forward=model.forward, network = temp_TwoLayerNet, x=x_train_normalize[1:batch_mask,], t_train_onehotlabel[1:batch_mask,])$loss윗 코드를 실행하면 다음과 같은 결과가 나옵니다.
>loss_value
=======
grads <- gradient(model.forward=model.forward, x=x_train_normalize[1:batch_size,], t= t_train_onehotlabel[1:batch_size,])
loss_value <- loss(model.forward=model.forward, x=x_train_normalize[1:batch_size,], t_train_onehotlabel[1:batch_size,])$loss
loss_value
>>>>>>> 1d79622fc87995d2f04d929befa789a06ab79210
[1] 2.302899이렇게 돌아가는 모델을 평가하는 평가 함수를 만들겠습니다.
model.evaluate <- function(model, network, x, t){
temp <- model(network, x)
y <- max.col(temp$x)
t <- max.col(t)
accuracy <- (sum(ifelse(y == t,1,0))) / dim(x)[1]
return(accuracy)
}실제로 무식하게 돌려봅니다.
for(i in 1:2000){
batch_mask <- sample(train_size ,batch_size)
x_batch <- x_train_normalize[batch_mask,]
t_batch <- t_train_onehotlabel[batch_mask,]
grad <- gradient(model.forward = model.forward, network = temp_TwoLayerNet, x_batch, t_batch)
temp_TwoLayerNet <- sgd.update(temp_TwoLayerNet, grad)
loss_value <- loss(model.forward=model.forward, network = temp_TwoLayerNet, x_batch, t_batch)$loss
train_loss_list <- rbind(train_loss_list,loss_value)
if(i %% iter_per_epoch == 0){
train_acc <- model.evaluate(model.forward, temp_TwoLayerNet, x_train_normalize, t_train_onehotlabel)
test_acc <- model.evaluate(model.forward, temp_TwoLayerNet, x_test_normalize, t_test_onehotlabel)
train_acc_list <- rbind(train_acc_list,train_acc)
test_acc_list <- rbind(test_acc_list,test_acc)
print(c(train_acc, test_acc))
}
}