배치 정규화를 통한 역 전파의 매트릭스 형태 = gamma){ xs <- scale(x)

배치 정규화 는 심층 신경망에서 상당한 성능 향상으로 인정되었습니다. 인터넷에 많은 자료가 활성화별로이를 구현하는 방법을 보여줍니다. 나는 이미 행렬 대수를 사용하여 backprop를 구현했으며, 고밀도 언어 ( Rcpp고밀도 행렬 곱셈 에 (그리고 결국 GPU)에 의존하는 동안 )에서 모든 것을 추출하고 for-loops를 사용하면 코드가 느려질 것입니다 대단한 고통에 더해

배치 정규화 함수는

b(xp)=γ(xp−μxp)σxp−1+β


.


  • xp

    는활성화되기 전의 p

    번째 노드입니다.

  • γ

    β

    는 스칼라 파라미터입니다

  • μxp

    σxp

    평균 및 SD있는 xp

    . (분산의 제곱근에 퍼지 계수와 일반적으로 퍼지 계수가 사용됩니다. 압축을 위해 0이 아닌 요소를 가정 해 봅시다)

매트릭스 형태에서, 전체 층에 대한 배치 정규화는

b(X)=(γ⊗1p)⊙(X−μX)⊙σX−1+(β⊗1p)


.


  • X

    N×p


  • 1N

    1 의 열 벡터입니다.

  • γ

    β

    는 이제계층 별 정규화 파라미터의행 p

    벡터이다
  • σ X N × p 행렬이며, 각 열은 열별평균 및 표준 편차의 N- 벡터입니다.
    μX

    σX

    N×p

    N

  • 는 Kronecker 제품이고 는 요소 별 (Hadamard) 제품입니다

배치 정규화가없고 연속적인 결과가없는 매우 간단한 단층 신경망은

y=a(XΓ1)Γ2+ϵ

어디

  • p 1 × p 2
    Γ1

    p1×p2

  • p 2 × 1
    Γ2

    p2×1

  • 는 활성화 함수입니다
    a(.)

손실의 경우 다음, 기울기는
R

R=N−1∑(y−y^)2

∂R∂Γ1=−2VTϵ^∂R∂Γ2=XT(a′(XΓ1)⊙−2ϵ^Γ2T)

어디


  • V=a(XΓ1)


  • ϵ^=y−y^

배치 정규화 하에서,
순은
또는
y = a ( ( γ 1 N )( X Γ 1μ X Γ 1 )σ 1 X Γ 1 + ( β 1 N ) ) Γ 2

y=a(b(XΓ1))Γ2

y=a((γ⊗1N)⊙(XΓ1−μXΓ1)⊙σXΓ1−1+(β⊗1N))Γ2


Hadamard 및 Kronecker 제품의 파생 상품을 계산하는 방법을 모르겠습니다. 크로네 커 (Kronecker) 제품의 주제에 관한 문헌 은 상당히 비현실적이다.

행렬 프레임 워크 내에 , R /βR /Γ 1 을 계산하는 실용적인 방법이 있습니까? 노드 별 계산에 의존하지 않고 간단한 표현?

∂R/∂γ

∂R/∂β

∂R/∂Γ1

업데이트 1 :

∂R/∂β

1NT(a′(XΓ1)⊙−2ϵ^Γ2T)

set.seed(1)
library(dplyr)
library(foreach)

#numbers of obs, variables, and hidden layers
N <- 10
p1 <- 7
p2 <- 4
a <- function (v) {
  v[v < 0] <- 0
  v
}
ap <- function (v) {
  v[v < 0] <- 0
  v[v >= 0] <- 1
  v
}

# parameters
G1 <- matrix(rnorm(p1*p2), nrow = p1)
G2 <- rnorm(p2)
gamma <- 1:p2+1
beta <- (1:p2+1)*-1
# error
u <- rnorm(10)

# matrix batch norm function
b <- function(x, bet = beta, gam = gamma){
  xs <- scale(x)
  gk <- t(matrix(gam)) %x% matrix(rep(1, N))
  bk <- t(matrix(bet)) %x% matrix(rep(1, N))
  gk*xs+bk
}
# activation-wise batch norm function
bi <- function(x, i){
  xs <- scale(x)
  gk <- t(matrix(gamma[i]))
  bk <- t(matrix(beta[i]))
  suppressWarnings(gk*xs[,i]+bk)
}

X <- round(runif(N*p1, -5, 5)) %>% matrix(nrow = N)
# the neural net
y <- a(b(X %*% G1)) %*% G2 + u

그런 다음 파생 상품을 계산하십시오.

# drdbeta -- the matrix way
drdb <- matrix(rep(1, N*1), nrow = 1) %*% (-2*u %*% t(G2) * ap(b(X%*%G1)))
drdb
           [,1]      [,2]    [,3]        [,4]
[1,] -0.4460901 0.3899186 1.26758 -0.09589582
# the looping way
foreach(i = 1:4, .combine = c) %do%{
  sum(-2*u*matrix(ap(bi(X[,i, drop = FALSE]%*%G1[i,], i)))*G2[i])
}
[1] -0.44609015  0.38991862  1.26758024 -0.09589582

β⊗1N

∂A⊗B∂A=(Inq⊗Tmp)(In⊗vec(B)⊗Im)

m

n

p

q

A

B

T
# playing with the kroneker derivative rule
A <- t(matrix(beta))
B <- matrix(rep(1, N))
diag(rep(1, ncol(A) *ncol(B))) %*% diag(rep(1, ncol(A))) %x% (B) %x% diag(nrow(A))
     [,1] [,2] [,3] [,4]
 [1,]    1    0    0    0
 [2,]    1    0    0    0
 snip
[13,]    0    1    0    0
[14,]    0    1    0    0
snip
[28,]    0    0    1    0
[29,]    0    0    1    0
[snip
[39,]    0    0    0    1
[40,]    0    0    0    1

γ

Γ1

β⊗1

업데이트 2

∂R/∂Γ1

∂R/∂γ

vec()

∂R/∂Γ1

w⊙XΓ1

Γ1

w≡(γ⊗1)⊙σXΓ1−1

w⊙X

w

X

∂(A⊙B)=∂A⊙B+A⊙∂B

과에서 , 그

∂vec(w⊙XΓ1)∂vec(Γ1)T=vec(XΓ1)I∂vec(w)∂vec(Γ1)T+vec(w)I∂vec(XΓ1)∂vec(Γ1)T

업데이트 3

여기에서 진보하고 있습니다. 나는 지난 밤 2시에이 아이디어로 일어났다. 수학은 수면에 좋지 않습니다.

∂R/∂Γ1

  • w≡(γ⊗1)⊙σXΓ1−1


  • “stub”≡a′(b(XΓ1))⊙−2ϵ^Γ2T

∂R∂Γ1=∂w⊙XΓ1∂Γ1(“stub”)

i

j

I

∂R∂Γij=(wi⊙Xi)T(“stub”j)


∂R∂Γij=(IwiXi)T(“stub”j)


∂R∂Γij=XiTIwi(“stub”j)

∂R∂Γ=XT(“stub”⊙w)

그리고 실제로는 :

stub <- (-2*u %*% t(G2) * ap(b(X%*%G1)))
w <- t(matrix(gamma)) %x% matrix(rep(1, N)) * (apply(X%*%G1, 2, sd) %>% t %x% matrix(rep(1, N)))
drdG1 <- t(X) %*% (stub*w)

loop_drdG1 <- drdG1*NA
for (i in 1:7){
  for (j in 1:4){
    loop_drdG1[i,j] <- t(X[,i]) %*% diag(w[,j]) %*% (stub[,j])
  }
}

> loop_drdG1
           [,1]       [,2]       [,3]       [,4]
[1,] -61.531877  122.66157  360.08132 -51.666215
[2,]   7.047767  -14.04947  -41.24316   5.917769
[3,] 124.157678 -247.50384 -726.56422 104.250961
[4,]  44.151682  -88.01478 -258.37333  37.072659
[5,]  22.478082  -44.80924 -131.54056  18.874078
[6,]  22.098857  -44.05327 -129.32135  18.555655
[7,]  79.617345 -158.71430 -465.91653  66.851965
> drdG1
           [,1]       [,2]       [,3]       [,4]
[1,] -61.531877  122.66157  360.08132 -51.666215
[2,]   7.047767  -14.04947  -41.24316   5.917769
[3,] 124.157678 -247.50384 -726.56422 104.250961
[4,]  44.151682  -88.01478 -258.37333  37.072659
[5,]  22.478082  -44.80924 -131.54056  18.874078
[6,]  22.098857  -44.05327 -129.32135  18.555655
[7,]  79.617345 -158.71430 -465.91653  66.851965

업데이트 4

∂R/∂γ

  • XΓ~≡(XΓ−μXΓ)⊙σXΓ−1


  • γ~≡γ⊗1N

이전과 마찬가지로 체인 규칙은 까지

∂R∂γ~=∂γ~⊙XΓ~∂γ~(“stub”)

∂R∂γ~i=(XΓ~)iTIγ~i(“stub”i)

∂R∂γ~=(XΓ~)T(“stub”⊙γ~)

그것은 일종의 일치합니다.

drdg <- t(scale(X %*% G1)) %*% (stub * t(matrix(gamma)) %x% matrix(rep(1, N)))

loop_drdg <- foreach(i = 1:4, .combine = c) %do% {
  t(scale(X %*% G1)[,i]) %*% (stub[,i, drop = F] * gamma[i])
}

> drdg
           [,1]      [,2]       [,3]       [,4]
[1,]  0.8580574 -1.125017  -4.876398  0.4611406
[2,] -4.5463304  5.960787  25.837103 -2.4433071
[3,]  2.0706860 -2.714919 -11.767849  1.1128364
[4,] -8.5641868 11.228681  48.670853 -4.6025996
> loop_drdg
[1]   0.8580574   5.9607870 -11.7678486  -4.6025996

γ

본인의 질문에 답변 한 것 같지만 본인이
맞는지 잘 모르겠습니다. 이 시점에서 나는 내가 함께 해킹 한 것을 엄격하게 증명 (또는 반증)하는 대답을 받아 들일 것이다.

while(not_answered){
  print("Bueller?")
  Sys.sleep(1)
}


답변

b(X)=(X−eNμXT)ΓΣX−1/2+eNβT

Γ=diag⁡(γ)

ΣX−1/2=diag⁡(σX1−1,σX2−1,…)

eN

∇βR=[−2ϵ^(Γ2T⊗I)JX(a)(I⊗eN)]T

−2ϵ^(Γ2T⊗I)=vec⁡(−2ϵ^Γ2T)T

JX(a)=diag⁡(vec⁡(a′(b(XΓ1))))

∇βR=(I⊗eNT)vec⁡(a′(b(XΓ1))⊙−2ϵ^Γ2T)=eNT(a′(b(XΓ1))⊙−2ϵ^Γ2T)

vec⁡(AXB)=(BT⊗A)vec⁡(X)

∇γR=[−2ϵ^(Γ2T⊗I)JX(a)(ΣXΓ1−1/2⊗(XΓ1−eNμXΓ1T))K]T=KTvec⁡((XΓ1−eNμXΓ1T)TWΣXΓ1−1/2)=diag⁡((XΓ1−eNμXΓ1T)TWΣXΓ1−1/2)

W=a′(b(XΓ1))⊙−2ϵ^Γ2T

K

Np×p

dΓi≠j=0

b

γi

γi

Γ1

w

ΣX

μX

X