@@ -149,57 +149,48 @@ def backward(ctx, grad_output):
149149 component_scale_sqr = torch .pow (component_scale , 2.0 ) # j
150150 epsilons = z / coord_scale # l i
151151 epsilons_sqr = torch .pow (epsilons , 2.0 ) # l i
152- r_sqr = epsilons_sqr .sum (- 1 , keepdim = True ) # l
152+ r_sqr = epsilons_sqr .sum (- 1 , keepdim = True ) # l 1
153153 r_sqr_j = r_sqr / component_scale_sqr # l j
154154 log_coord_scale_product = coord_scale .log ().sum ()
155155 log_component_scale_power = component_scale .log () * float (dim )
156-
157- log_q_j = (
158- - 0.5 * r_sqr_j
159- - 0.5 * math .log (2.0 * math .pi ) * float (dim )
160- - log_coord_scale_product
161- - log_component_scale_power
162- )
163- log_q_tot = torch .logsumexp (pis .log () + log_q_j , dim = - 1 , keepdim = True )
164- q_j_over_q_tot = torch .exp (log_q_j - log_q_tot )
165-
166- log_normalizer = (
167- - 0.5 * math .log (2.0 * math .pi ) * float (dim )
168- - log_component_scale_power
169- - log_coord_scale_product
170- - log_q_tot
171- )
172-
173- Phi_j = torch .exp (- 0.5 * r_sqr_j + log_normalizer )
156+
157+ log_gaussian_normalizer = (
158+ 0.5 * math .log (2.0 * math .pi ) * float (dim )
159+ + log_coord_scale_product
160+ + log_component_scale_power
161+ ).unsqueeze (0 ) # 1 j
162+
163+ log_q_j = - 0.5 * r_sqr_j - log_gaussian_normalizer # l j
164+ log_q_tot = torch .logsumexp (pis .log () + log_q_j , dim = - 1 , keepdim = True ) # l 1
165+ posterior_j = torch .exp (pis .log () + log_q_j - log_q_tot ) # l j
166+ Phi_j = torch .exp (- 0.5 * r_sqr_j ) # l j
174167
175168 exponents = - torch .arange (
176169 1.0 , int (dim / 2 ) + 1.0 , 1.0 , device = z .device , dtype = z .dtype
177170 )
178171 if z .dim () > 1 :
179- r_j_poly = r_sqr_j .unsqueeze (- 1 ).expand (- 1 , - 1 , int (dim / 2 ))
172+ r_j_poly = r_sqr_j .unsqueeze (- 1 ).expand (- 1 , - 1 , int (dim / 2 )) # l j d/2
180173 else :
181- r_j_poly = r_sqr_j .unsqueeze (- 1 ).expand (- 1 , int (dim / 2 ))
174+ r_j_poly = r_sqr_j .unsqueeze (- 1 ).expand (- 1 , int (dim / 2 )) # l j d/2
182175 r_j_poly = coeffs * torch .pow (r_j_poly , exponents )
183176 Phi_j *= r_j_poly .sum (- 1 )
184177 if dim % 2 == 1 :
185178 root_two = math .sqrt (2.0 )
186179 extra_term = (
187180 coeffs [- 1 ]
188181 * math .sqrt (0.5 * math .pi )
189- * (1.0 - torch .erf (r_sqr_j .sqrt () / root_two ))
190- )
191- Phi_j += (
192- extra_term
193- * torch .pow (r_sqr_j , - 0.5 * float (dim ))
194- * torch .exp (log_normalizer )
195- )
196-
197- logits_grad = (z .unsqueeze (- 2 ) * Phi_j .unsqueeze (- 1 ) * g ).sum (- 1 )
182+ * torch .erfc (r_sqr_j .sqrt () / root_two )) # l j
183+ Phi_j += extra_term * torch .pow (r_sqr_j , - 0.5 * float (dim ))
184+
185+ logits_grad = (z .unsqueeze (- 2 ) * Phi_j .unsqueeze (- 1 ) * g ).sum (- 1 ) # l j
186+
187+ log_logits_scale = - log_gaussian_normalizer - log_q_tot # l j
188+ logits_grad = logits_grad * torch .exp (log_logits_scale ) # l j
198189 logits_grad = sum_leftmost (logits_grad , - 1 )
199190 logits_grad = pis * logits_grad
200191 logits_grad = logits_grad - logits_grad .sum () * pis
201192
202- prefactor = pis . unsqueeze ( - 1 ) * q_j_over_q_tot .unsqueeze (- 1 ) * g # l j i
193+ prefactor = posterior_j .unsqueeze (- 1 ) * g # l j i
203194 coord_scale_grad = sum_leftmost (prefactor * epsilons .unsqueeze (- 2 ), - 1 )
204195 component_scale_grad = sum_leftmost (
205196 (prefactor * z .unsqueeze (- 2 )).sum (- 1 ) / component_scale , - 1
0 commit comments