why_n-1_gradient_explanation
Differences
This shows you the differences between two versions of the page.
Next revision | Previous revision | ||
why_n-1_gradient_explanation [2025/09/04 10:33] – created hkimscil | why_n-1_gradient_explanation [2025/09/05 19:51] (current) – [리소스를 많이 사용하지 않고 msr값이 최소가 되는 v값을 찾는 방법] hkimscil | ||
---|---|---|---|
Line 1: | Line 1: | ||
+ | ====== mean X를 중심으로 x값들을 구해서 (x-v)에 사용하는 경우 ====== | ||
+ | |||
< | < | ||
# | # | ||
Line 4: | Line 6: | ||
rm(list=ls()) | rm(list=ls()) | ||
+ | # rnorm 펑션을 변형한 펑션으로 | ||
+ | # mean값과 sd값을 같는 n개의 샘플원소를 | ||
+ | # 구한다. (샘플의 평균과 표준편차가 | ||
+ | # 정확히 원하는 값이 되도록 함) | ||
rnorm2 <- function(n, | rnorm2 <- function(n, | ||
mean+sd*scale(rnorm(n)) | mean+sd*scale(rnorm(n)) | ||
Line 11: | Line 17: | ||
nx <- 1000 | nx <- 1000 | ||
mx <- 50 | mx <- 50 | ||
- | sdx <- mx * 0.15 | + | sdx <- mx * 0.1 |
+ | sdx # 5 | ||
x <- rnorm2(nx, mx, sdx) | x <- rnorm2(nx, mx, sdx) | ||
+ | # x <- rnorm2(1000, | ||
mean(x) | mean(x) | ||
Line 19: | Line 27: | ||
hist(x) | hist(x) | ||
- | x.span <- seq(from = mean(x)-4*sd(x), | + | x.span <- seq(from = mean(x)-3*sd(x), |
- | to = mean(x)+4*sd(x), | + | to = mean(x)+3*sd(x), |
- | by = 0.1) | + | by = .1) |
residuals <- function(x, v) { | residuals <- function(x, v) { | ||
Line 27: | Line 35: | ||
} | } | ||
- | ssr <- function(x, v) { | + | # sum of square residual 값을 |
+ | # 구하는 펑션 | ||
+ | ssr <- function(x, v) { | ||
residuals <- (x - v) | residuals <- (x - v) | ||
return(sum(residuals^2)) | return(sum(residuals^2)) | ||
} | } | ||
+ | # mean square residual 값을 | ||
+ | # 구하는 펑션 (mean square | ||
+ | # residual = variance) | ||
msr <- function(x, v) { | msr <- function(x, v) { | ||
residuals <- (x - v) | residuals <- (x - v) | ||
- | # return((sum(residuals^2))/ | + | # return((sum(residuals^2))/ |
return((mean(residuals^2))) | return((mean(residuals^2))) | ||
} | } | ||
- | srs <- c() # sum of residuals | ||
ssrs <- c() # sum of square residuals | ssrs <- c() # sum of square residuals | ||
msrs <- c() # mean square residuals = variance | msrs <- c() # mean square residuals = variance | ||
vs <- c() # the value of v in (x - v) | vs <- c() # the value of v in (x - v) | ||
+ | |||
+ | x.span | ||
+ | # x.span의 값들을 v값으로 삼아 | ||
+ | # sum(x-x.span)^2 처럼 구하면 | ||
+ | # SS값을 구한 것이 된다. | ||
+ | # 우리가 배운 SS값은 x.span의 | ||
+ | # 값으로 샘플의 평균을 사용했을 때의 | ||
+ | # residual 값이다. | ||
+ | # x.span은 샘플의 평균을 중심으로 | ||
+ | # 여러가지 값을 사용하는 것을 | ||
+ | # 가정한다. | ||
+ | |||
+ | |||
for (i in x.span) { | for (i in x.span) { | ||
res.x <- residuals(x, | res.x <- residuals(x, | ||
- | | + | # |
ssr.x <- ssr(x,i) | ssr.x <- ssr(x,i) | ||
msr.x <- msr(x,i) | msr.x <- msr(x,i) | ||
- | | + | # |
ssrs <- append(ssrs, | ssrs <- append(ssrs, | ||
msrs <- append(msrs, | msrs <- append(msrs, | ||
vs <- append(vs, i) | vs <- append(vs, i) | ||
} | } | ||
+ | # 아래 plot은 SS값들이나 (두번째는) | ||
+ | # MS값들을 v값이 변화함에 따라서 | ||
+ | # (x.span의 범위에 따라서 변화) | ||
+ | # 어떻게 변화하는지 구한 것 | ||
plot(ssrs) | plot(ssrs) | ||
plot(msrs) | plot(msrs) | ||
- | plot(srs) | ||
+ | |||
+ | # 아래는 위에서 계산한 msr 값들을 저장한 | ||
+ | # msrs값들 중에서 최소값이 되는 것을 찾은 | ||
+ | # 것. 우리는 이것이 샘플의 평균임을 안다. | ||
min(msrs) | min(msrs) | ||
+ | # 최소값일 때의 위치 (msrs에서 몇번째인지) | ||
min.pos.msrs <- which(msrs == min(msrs)) | min.pos.msrs <- which(msrs == min(msrs)) | ||
min.pos.msrs | min.pos.msrs | ||
+ | # 그 위치에 해당하는 (그 때 사용된) v값 | ||
print(vs[min.pos.msrs]) | print(vs[min.pos.msrs]) | ||
- | mean(x) | + | </ |
- | plot(vs, msrs) | + | |
- | plot(vs, ssrs) | + | |
+ | 다시 설명하면 위의 코드는 [sum(x-mean(x)^2 / n]을 (= ms값 혹은 분산값임) 구하는 식에 mean(x)대신에 다양한 x값을 넣어 본 것이다. 그리고, 이 때 ms값 중에서 최소값이 되는 지점을 찾아서 이 때 사용된 v값을 (mean(x)대신에 사용된) 알아 본것이다. 이 v값이 mean(x)이 되는 것을 확인하여 mean(x)값으로 빼서 구한 SS값이 가장 작은 ms값을 (혹은 SS값을) 갖는다는 것을 보여준다. | ||
+ | |||
+ | |||
+ | ====== 리소스를 많이 사용하지 않고 msr값이 최소가 되는 v값을 찾는 방법 ====== | ||
+ | |||
+ | 위 방법의 단점은 x.span의 값을 길게 나열하여 한번씩 넣어서 msr값을 구하여 최소값을 보는데 리소스를 너무 사용한다는 것이다. | ||
+ | 아래는 그 단점을 극복하는 방법이다. | ||
+ | <WRAP group> | ||
+ | <WRAP half column> | ||
+ | < | ||
# the above no gradient | # the above no gradient | ||
- | # mse 값으로 계산 rather than sse | ||
- | # 후자는 값이 너무 커짐 | ||
gradient <- function(x, v){ | gradient <- function(x, v){ | ||
residuals = x - v | residuals = x - v | ||
- | # y = (x-v)^2 | + | # y = (sum(x-v)^2)/n 혹은 (mean(x-v)^2) |
- | # dy/dv = 2(x-v)*-1 chain rule | + | # 의 식이 ms값을 구하는 식인데 |
- | # dy/dv = -2(x-v) | + | # 이를 v에 대해서 미분하면 chain rule을 써야 한다 |
+ | # 자세한 것은 http:// | ||
+ | # 문서 중에 미분 부분 참조 | ||
+ | # dy/dv = ( 2(x-v)*-1 | ||
+ | # dy/dv = -2 (x-v) / n = -2 (mean(residual)) | ||
dx = -2 * mean(residuals) | dx = -2 * mean(residuals) | ||
- | return(list(" | + | |
+ | return(dx) | ||
} # function returns ds value | } # function returns ds value | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | > | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP half column> | ||
+ | 이후 일련의 코드의 목적은 v값이 최소값이 되는 지점을 자동적으로 찾아보려는 것이다. 이것을 위해서 우선 v값으로 사용할 첫 점수를 랜덤하게 구한 후 (아래 그래프에서 빨간색 지점), 자동적으로 그 다음 v 점수를 찾고 (녹색지점), | ||
+ | * gradient function과 | ||
+ | * learning_rate 값이다. | ||
+ | gradient 펑션은 dy/dv 의 연쇄 미분식인 ([[:chain rules]]) -2(x-v) / n = -2 mean(res) 값을 구하는 것이다. 이렇게 구한 값에 learning_rate값을 곱한후, 이것을 먼저 사용한 v값에서 (빨간색 지점) 빼 주어 다음 v값으로 (녹색지점) 사용하려고 한다. 이 녹색지점에서의 v값을 사용했을 때의 gradient값을 구한 후 다시 이값에 learning_rate인 0.1을 곱하여 그 다음 v값을 구하여 사용한다. 이렇게 구하는 v값들은 0.1씩 곱해주는 효과때문에 오른 쪽으로 옮겨가는 지점이 "< | ||
+ | |||
+ | |||
+ | {{: | ||
+ | |||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | <WRAP group> | ||
+ | <WRAP half column> | ||
+ | < | ||
residuals <- function(x, v) { | residuals <- function(x, v) { | ||
return(x - v) | return(x - v) | ||
Line 92: | Line 168: | ||
# return(mean(residuals^2)) | # return(mean(residuals^2)) | ||
} | } | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP half column> | ||
+ | msr값을 구하기 위한 function | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP group> | ||
+ | <WRAP half column> | ||
+ | < | ||
+ | zx <- (x-mean(x))/ | ||
# pick one random v in (x-v) | # pick one random v in (x-v) | ||
v <- rnorm(1) | v <- rnorm(1) | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | |||
+ | > | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP half column> | ||
+ | comment | ||
+ | * 랜덤하게 v값을 찾음 '' | ||
+ | * 원래는 mean(x)값 근처의 값을 랜덤하게 골라야 하므로 | ||
+ | * '' | ||
+ | * 그렇게 하질 않고 x 집합의 원소들을 표준점수화 한 후 '' | ||
+ | * (이렇게 표준점수화 하면 x 변인의 평균이 0, 표준편차가 1 이 되는 집합으로 변한다) | ||
+ | * '' | ||
+ | * 이렇게 하는 이유는 혹시 나중에 다른 x집합에 똑같은 작업을 하더라도 그 집합의 평균과 표준편차를 사용하지 않고 | ||
+ | * 단순히 '' | ||
+ | |||
+ | </ | ||
+ | </ | ||
+ | |||
+ | |||
+ | <WRAP group> | ||
+ | <WRAP half column> | ||
+ | < | ||
# Train the model with scaled features | # Train the model with scaled features | ||
learning.rate = 1e-1 | learning.rate = 1e-1 | ||
+ | </ | ||
+ | </ | ||
+ | <WRAP half column> | ||
+ | comment | ||
+ | * 이 0.1은 gradient function으로 구한 해단 v값에 대한 y 기울기 값을 (미분값) | ||
+ | * 구한 후, 여기에 곱하기 위해서 지정한다. | ||
+ | </ | ||
+ | </ | ||
- | grads <- c() | + | <WRAP group> |
- | ssrs <- c() | + | <WRAP half column> |
+ | |||
+ | < | ||
msrs <- c() | msrs <- c() | ||
- | mres <- c() | ||
vs <- c() | vs <- c() | ||
- | steps <- c() | ||
- | # Record Loss for each epoch: | ||
- | zx <- (x-mean(x))/ | ||
nlen <- 75 | nlen <- 75 | ||
for (epoch in 1:nlen) { | for (epoch in 1:nlen) { | ||
residual <- residuals(zx, | residual <- residuals(zx, | ||
- | | + | msr.x <- msr(zx, v) |
- | # msr.x <- msr(zx, v) | + | |
- | # ssrs <- append(ssrs, | + | |
- | # msrs <- append(msrs, | + | |
| | ||
grad <- gradient(zx, | grad <- gradient(zx, | ||
- | | + | step.v <- grad * learning.rate # |
- | | + | v <- v - step.v |
- | | + | vs <- append(vs, v) # v값 저장 |
- | v <- v - step.v | + | |
- | vs <- append(vs, v) | + | |
} | } | ||
- | tail(grads) | ||
- | tail(srs) | ||
tail(msrs) | tail(msrs) | ||
- | tail(ssrs) | ||
tail(vs) | tail(vs) | ||
- | plot(srs) | ||
plot(msrs) | plot(msrs) | ||
- | plot(ssrs) | ||
plot(vs) | plot(vs) | ||
- | plot(grads) | + | </ |
+ | </ | ||
+ | <WRAP half column> | ||
+ | comment | ||
+ | </ | ||
+ | </ | ||
+ | |||
+ | <WRAP group> | ||
+ | <WRAP half column> | ||
+ | < | ||
# scaled | # scaled | ||
- | v | + | vs # 변화하는 |
- | # zx <- (x-mean(x))/ | + | |
- | # v.표준화 <- (v.원래 - mean(x))/ | + | |
- | v.orig <- (v*sd(x))+mean(x) | + | |
- | v.orig | + | |
- | + | ||
- | steps | + | |
vs.orig <- (vs*sd(x))+mean(x) | vs.orig <- (vs*sd(x))+mean(x) | ||
vs.orig | vs.orig | ||
- | grads | ||
- | |||
+ | # 마지막 v값이 최소값에 근접한 값 | ||
+ | v | ||
+ | v.orig <- (v*sd(x))+mean(x) | ||
+ | v.orig | ||
</ | </ | ||
+ | </ | ||
+ | <WRAP half column> | ||
+ | comment | ||
+ | </ | ||
+ | </ |
why_n-1_gradient_explanation.1756949607.txt.gz · Last modified: 2025/09/04 10:33 by hkimscil