def dlogp(inputs, gradients): (g_logp, ) = gradients cov, delta = inputs g_logp.tag.test_value = floatX(1.0) n, k = delta.shape chol_cov = cholesky(cov) diag = aet.nlinalg.diag(chol_cov) ok = aet.all(diag > 0) chol_cov = aet.switch(ok, chol_cov, aet.fill(chol_cov, 1)) delta_trans = solve_lower(chol_cov, delta.T).T inner = n * aet.eye(k) - aet.dot(delta_trans.T, delta_trans) g_cov = solve_upper(chol_cov.T, inner) g_cov = solve_upper(chol_cov.T, g_cov.T) tau_delta = solve_upper(chol_cov.T, delta_trans.T) g_delta = tau_delta.T g_cov = aet.switch(ok, g_cov, -np.nan) g_delta = aet.switch(ok, g_delta, -np.nan) return [-0.5 * g_cov * g_logp, -g_delta * g_logp]
def test_1msigmoid(self): if not register_local_1msigmoid: return m = self.get_mode() x = fmatrix() # tests exp_over_1_plus_exp f = aesara.function([x], 1 - exp(x) / (1 + exp(x)), mode=m) assert check_stack_trace(f, ops_to_check=[neg, sigmoid_inplace]) assert [node.op for node in f.maker.fgraph.toposort()] == [ neg, sigmoid_inplace, ] # tests inv_1_plus_exp f = aesara.function([x], 1 - aet.fill(x, 1.0) / (1 + exp(-x)), mode=m) assert check_stack_trace(f, ops_to_check=[neg, sigmoid_inplace]) assert [node.op for node in f.maker.fgraph.toposort()] == [ neg, sigmoid_inplace, ]
def test_exp_over_1_plus_exp(self): m = self.get_mode(excluding=["local_elemwise_fusion"]) x = vector() data = np.random.rand(54).astype(config.floatX) backup = config.warn__identify_1pexp_bug config.warn__identify_1pexp_bug = False try: # tests exp_over_1_plus_exp f = aesara.function([x], exp(x) / (1 + exp(x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] == [sigmoid] f(data) f = aesara.function([x], exp(x) / (2 + exp(x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid] f(data) f = aesara.function([x], exp(x) / (1 - exp(x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid] f(data) f = aesara.function([x], exp(x + 1) / (1 + exp(x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid] f(data) # tests inv_1_plus_exp f = aesara.function([x], aet.fill(x, 1.0) / (1 + exp(-x)), mode=m) # todo: solve issue #4589 first # assert check_stack_trace(f, ops_to_check=sigmoid) assert [node.op for node in f.maker.fgraph.toposort()] == [sigmoid] f(data) f = aesara.function([x], aet.fill(x, 1.0) / (2 + exp(-x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid] f(data) f = aesara.function([x], aet.fill(x, 1.0) / (1 - exp(-x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid] f(data) f = aesara.function([x], aet.fill(x, 1.1) / (1 + exp(-x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [sigmoid] f(data) # tests inv_1_plus_exp with neg f = aesara.function([x], aet.fill(x, -1.0) / (1 + exp(-x)), mode=m) # todo: solve issue #4589 first # assert check_stack_trace( # f, ops_to_check=[sigmoid, neg_inplace]) assert [node.op for node in f.maker.fgraph.toposort()] == [ sigmoid, neg_inplace, ] f(data) f = aesara.function([x], aet.fill(x, -1.0) / (1 - exp(-x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [ sigmoid, neg_inplace, ] f(data) f = aesara.function([x], aet.fill(x, -1.0) / (2 + exp(-x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [ sigmoid, neg_inplace, ] f(data) f = aesara.function([x], aet.fill(x, -1.1) / (1 + exp(-x)), mode=m) assert [node.op for node in f.maker.fgraph.toposort()] != [ sigmoid, neg_inplace, ] f(data) # tests double inv_1_plus_exp with neg # (-1)(exp(x)) / (1+exp(x))(1+exp(-x)) # = (-1)/(1+exp(-x)) * exp(x)/(1+exp(x)) # = - (sigm(x) * sigm(x)) f = aesara.function( [x], (aet.fill(x, -1.0) * exp(x)) / ((1 + exp(x)) * (1 + exp(-x))), mode=m, ) # todo: solve issue #4589 first # assert check_stack_trace(f, ops_to_check=[sigmoid, mul]) assert [node.op for node in f.maker.fgraph.toposort()] == [sigmoid, mul] f(data) f = aesara.function( [x], (aet.fill(x, -1.1) * exp(x)) / ((1 + exp(x)) * (1 + exp(-x))), mode=m, ) assert [node.op for node in f.maker.fgraph.toposort()] != [ sigmoid, mul, neg_inplace, ] f(data) f = aesara.function( [x], (aet.fill(x, -1.0) * exp(x)) / ((2 + exp(x)) * (1 + exp(-x))), mode=m, ) assert [node.op for node in f.maker.fgraph.toposort()] != [ sigmoid, mul, neg_inplace, ] f(data) f = aesara.function( [x], (aet.fill(x, -1.0) * exp(x)) / ((1 + exp(x)) * (2 + exp(-x))), mode=m, ) assert [node.op for node in f.maker.fgraph.toposort()] != [ sigmoid, mul, neg_inplace, ] f(data) f = aesara.function( [x], (aet.fill(x, -1.0) * exp(x)) / ((1 + exp(x)) * (1 + exp(x))), mode=m, ) assert [node.op for node in f.maker.fgraph.toposort()] != [ sigmoid, mul, neg_inplace, ] f(data) f = aesara.function( [x], (aet.fill(x, -1.0) * exp(x)) / ((1 + exp(x)) * (2 + exp(-x))), mode=m, ) assert [node.op for node in f.maker.fgraph.toposort()] != [ sigmoid, mul, neg_inplace, ] f(data) finally: # Restore config option. config.warn__identify_1pexp_bug = backup
def MvNormalLogp(): """Compute the log pdf of a multivariate normal distribution. This should be used in MvNormal.logp once Theano#5908 is released. Parameters ---------- cov: aet.matrix The covariance matrix. delta: aet.matrix Array of deviations from the mean. """ cov = aet.matrix("cov") cov.tag.test_value = floatX(np.eye(3)) delta = aet.matrix("delta") delta.tag.test_value = floatX(np.zeros((2, 3))) solve_lower = Solve(A_structure="lower_triangular") solve_upper = Solve(A_structure="upper_triangular") cholesky = Cholesky(lower=True, on_error="nan") n, k = delta.shape n, k = f(n), f(k) chol_cov = cholesky(cov) diag = aet.nlinalg.diag(chol_cov) ok = aet.all(diag > 0) chol_cov = aet.switch(ok, chol_cov, aet.fill(chol_cov, 1)) delta_trans = solve_lower(chol_cov, delta.T).T result = n * k * aet.log(f(2) * np.pi) result += f(2) * n * aet.sum(aet.log(diag)) result += (delta_trans**f(2)).sum() result = f(-0.5) * result logp = aet.switch(ok, result, -np.inf) def dlogp(inputs, gradients): (g_logp, ) = gradients cov, delta = inputs g_logp.tag.test_value = floatX(1.0) n, k = delta.shape chol_cov = cholesky(cov) diag = aet.nlinalg.diag(chol_cov) ok = aet.all(diag > 0) chol_cov = aet.switch(ok, chol_cov, aet.fill(chol_cov, 1)) delta_trans = solve_lower(chol_cov, delta.T).T inner = n * aet.eye(k) - aet.dot(delta_trans.T, delta_trans) g_cov = solve_upper(chol_cov.T, inner) g_cov = solve_upper(chol_cov.T, g_cov.T) tau_delta = solve_upper(chol_cov.T, delta_trans.T) g_delta = tau_delta.T g_cov = aet.switch(ok, g_cov, -np.nan) g_delta = aet.switch(ok, g_delta, -np.nan) return [-0.5 * g_cov * g_logp, -g_delta * g_logp] return OpFromGraph([cov, delta], [logp], grad_overrides=dlogp, inline=True)
def get_moment(cls, rv, size, *rv_inputs): mean = at.fill(size, rv.Y.mean()) return mean