하자 BE에 . 의 평균 및 공분산 행렬은 무엇입니까 (최대 계산 된 요소 별)?
예를 들어 딥 네트워크 내에서 ReLU 활성화 기능을 사용하고 CLT를 통해 주어진 레이어에 대한 입력이 거의 정상이라고 가정하면 출력 분포입니다.
(많은 사람들이 전에 이것을 계산했다고 확신하지만, 합리적으로 읽을 수있는 방법으로 어디서나 결과를 찾을 수 없었습니다.)
하자 BE에 . 의 평균 및 공분산 행렬은 무엇입니까 (최대 계산 된 요소 별)?
예를 들어 딥 네트워크 내에서 ReLU 활성화 기능을 사용하고 CLT를 통해 주어진 레이어에 대한 입력이 거의 정상이라고 가정하면 출력 분포입니다.
(많은 사람들이 전에 이것을 계산했다고 확신하지만, 합리적으로 읽을 수있는 방법으로 어디서나 결과를 찾을 수 없었습니다.)
답변:
우리는 먼저이 단지의 특정 순간에 의존 줄일 수 있습니다 단 변수 / 이변 량 절단 정규 분포 : 물론 참고
우리는 몇 가지 결과를 사용합니다
S 로젠 바움 (1961). 잘린 이변 량 정규 분포의 순간 . JRSS B, vol 23 pp 405-408. ( jstor )
로젠 바움은 이벤트 에 대한 잘림을 고려 합니다.
구체적으로, 그의 (1), (3) 및 (5)의 세 가지 결과를 사용합니다. 먼저 다음을 정의하십시오.
이제 Rosenbaum은 다음과 같이 표시합니다.
갖는 (1)과 (3)의 특수한 경우 , 즉 잘림을 고려하는 것도 유용합니다 .
이제
우리는 이는 , 일 때 및 값입니다. .
이제 (*)를 사용하여 및 (*) 및 (**)를 모두 사용하면 그래서
찾으려면 , 우리는해야합니다
순간을 계산하는 파이썬 코드는 다음과 같습니다.
import numpy as np
from scipy import stats
def relu_mvn_mean_cov(mu, Sigma):
mu = np.asarray(mu, dtype=float)
Sigma = np.asarray(Sigma, dtype=float)
d, = mu.shape
assert Sigma.shape == (d, d)
x = (slice(None), np.newaxis)
y = (np.newaxis, slice(None))
sigma2s = np.diagonal(Sigma)
sigmas = np.sqrt(sigma2s)
rhos = Sigma / sigmas[x] / sigmas[y]
prob = np.empty((d, d)) # prob[i, j] = Pr(X_i > 0, X_j > 0)
zero = np.zeros(d)
for i in range(d):
prob[i, i] = np.nan
for j in range(i + 1, d):
# Pr(X > 0) = Pr(-X < 0); X ~ N(mu, S) => -X ~ N(-mu, S)
s = [i, j]
prob[i, j] = prob[j, i] = stats.multivariate_normal.cdf(
zero[s], mean=-mu[s], cov=Sigma[np.ix_(s, s)])
mu_sigs = mu / sigmas
Q = stats.norm.cdf(mu_sigs)
q = stats.norm.pdf(mu_sigs)
mean = Q * mu + q * sigmas
# rho_cs is sqrt(1 - rhos**2); but don't calculate diagonal, because
# it'll just be zero and we're dividing by it (but not using result)
# use inf instead of nan; stats.norm.cdf doesn't like nan inputs
rho_cs = 1 - rhos**2
np.fill_diagonal(rho_cs, np.inf)
np.sqrt(rho_cs, out=rho_cs)
R = stats.norm.cdf((mu_sigs[y] - rhos * mu_sigs[x]) / rho_cs)
mu_sigs_sq = mu_sigs ** 2
r_num = mu_sigs_sq[x] + mu_sigs_sq[y] - 2 * rhos * mu_sigs[x] * mu_sigs[y]
np.fill_diagonal(r_num, 1) # don't want slightly negative numerator here
r = rho_cs / np.sqrt(2 * np.pi) * stats.norm.pdf(np.sqrt(r_num) / rho_cs)
bit = mu[y] * sigmas[x] * q[x] * R
cov = (
(mu[x] * mu[y] + Sigma) * prob
+ bit + bit.T
+ sigmas[x] * sigmas[y] * r
- mean[x] * mean[y])
cov[range(d), range(d)] = (
Q * (1 - Q) * mu**2 + (1 - 2 * Q) * q * mu * sigmas
+ (Q - q**2) * sigma2s)
return mean, cov
그리고 Monte Carlo 테스트가 작동하는지 테스트하십시오.
np.random.seed(12)
d = 4
mu = np.random.randn(d)
L = np.random.randn(d, d)
Sigma = L.T.dot(L)
dist = stats.multivariate_normal(mu, Sigma)
mn, cov = relu_mvn_mean_cov(mu, Sigma)
samps = dist.rvs(10**7)
mn_est = samps.mean(axis=0)
cov_est = np.cov(samps, rowvar=False)
print(np.max(np.abs(mn - mn_est)), np.max(np.abs(cov - cov_est)))
이는 0.000572145310512 0.00298692620286
청구 된 기대 및 공분산이 Monte Carlo 추정치 ( 샘플 기준)와 일치 함을 나타냅니다 .