torch 설치 문제
Can you try installing the VC++ redistributable runtime from here: https://support.microsoft.com/en-us/help/2977003/the-latest-supported-visual-c-downloads x64: vc_redist.x64.exe 설치
# torch 패키지를 불러오고 10x4 행렬을 생성한다. 숫자를 고정하기 위해 torch_manual_seed() 함수를 사용하였다.
torch_manual_seed(123)
x = torch_randn(10, 4)
x
## torch_tensor
## 0.3374 -0.1778 -0.3035 -0.5880
## 0.3486 0.6603 -0.2196 -0.3792
## 0.7671 -1.1925 0.6984 -1.4097
## 0.1794 1.8951 0.4954 0.2692
## -0.0770 -1.0205 -0.1690 0.9178
## 1.5810 1.3010 1.2753 -0.2010
## 0.9624 0.2492 -0.4845 -2.0929
## -0.8199 -0.4210 -0.9620 1.2825
## -0.3430 -0.6821 -0.9887 -1.7018
## -0.7498 -1.1285 0.4135 0.2892
## [ CPUFloatType{10,4} ]
# 신경망 구조 정의
# 먼저 is_torch_tensor() 함수와 nn_parameter() 함수를 정의해주는데 원 코드 출처를 각각 표기해놓았다. 이는 torch 0.1.0 이상을 사용한다면 굳이 정의하지 않아도 되기 때문에 이 코드 블럭은 무시해도 관계 없다. 참고로 패키지 버전 확인은 다음과 같이 packageVersion() 함수를 사용하면 된다.
packageVersion("torch")
## [1] '0.1.0'
# https://github.com/mlverse/torch/blob/master/R/tensor.R
is_torch_tensor <- function(x){
inherits(x, "torch_tensor")
}
# https://github.com/mlverse/torch/blob/master/R/nn.R
# x `requires_grad = TRUE` tells that we are going to take derivatives over it.
nn_parameter = function(x, requires_grad = TRUE){
if (!is_torch_tensor(x))
stop("`x` must be a tensor.")
x$requires_grad_(requires_grad)
class(x) = c(class(x), "nn_parameter")
x
}
# 신경망의 입출력을 지정하기 위해서 udf_init() 함수를 생성한다. 초기값은 임의값을 생성하는 torch_randn() 함수와 0을 생성하는 torch_zeros() 함수를 사용하였다. 그리고 udf_mm() 함수는 신경망의 연산을 담당하는데 torch_mm() 함수가 matrix multiplication 으로 행렬곱을 수행한다. 즉, 입력된 데이터를 한 줄씩 읽어 self$w (가중치)와 곱연산을 하고 self$b 와 합연산을 하는 것이다. 그리고 이 모든 사항을 dense 객체에 저장한다.
udf_init = function(in_features, out_features) {
self$w = nn_parameter(torch_randn(in_features, out_features))
self$b = nn_parameter(torch_zeros(out_features))
}
udf_mm = function(x){
torch_mm(x, self$w) + self$b # matrix multiplication
}
dense = nn_module(clasname = "dense",
initialize = udf_init,
forward = udf_mm)
# 하이퍼파라미터 설정
# 모델에 입력되는 숫자는 4개, 출력은 1개로 각각 in_features 와 out_features 인자에 지정하였다. 신경망을 생성하면서 첫 줄에 torch_manual_seed() 함수를 사용하였는데 이는 udf_init() 함수에서 torch_randn()을 사용하였기 때문에 고정해주지 않으면 다른 값이 생성되기 때문이다. 그리고 생성된 값은 model$parameters 로 볼 수 있으며 가중치와 절편을 개별로 보고자 할 경우 model$w와 model$b로 각각 볼 수 있다.
torch_manual_seed(123)
model = dense(in_features = 4,
out_features = 1)
model$parameters
## $w
## torch_tensor
## -0.1115
## 0.1204
## -0.3696
## -0.2404
## [ CPUFloatType{4,1} ]
##
## $b
## torch_tensor
## 0
## [ CPUFloatType{1} ]
# 학습
# 이제 데이터와 모델이 다 준비되었으니 데이터를 통과시킬 일만 남은 셈이다. 이 부분은 학습이라고 쓰긴 했지만 학습이라기 보다는 지정된 4원 1차 방정식에 숫자를 흘려보내는 그 이상도 이하도 아니다. y_pred_tensor 객체에 입력 데이터 10개 row에 대한 출력값 10개를 확인 할 수 있다.
y_pred_tensor = model(x)
y_pred_tensor
## torch_tensor
## 0.1946
## 0.2130
## -0.1483
## -0.0397
## -0.2724
## -0.4427
## 0.6050
## 0.0880
## 0.7307
## -0.2746
## [ CPUFloatType{10,1} ]
# 평가
# 앞에서 생성한 출력물을 기본 R 객체로 변환하여 행렬 연산을 해보고 신경망으로 연산한 것과 비교해보면 다음과 같다.
data_input = as.matrix(as_array(x))
model_weights = as.matrix(as_array(model$w))
model_bias = as.numeric(as_array(model$b))
y_pred_mat = data_input %*% model_weights + model_bias
y_pred_mat
## [,1]
## [1,] 0.19455942
## [2,] 0.21296745
## [3,] -0.14825251
## [4,] -0.03974358
## [5,] -0.27243680
## [6,] -0.44271172
## [7,] 0.60498009
## [8,] 0.08797316
## [9,] 0.73073653
## [10,] -0.27462250