def test_local_sigm_times_exp(self): """ Test the `local_sigm_times_exp` optimization. exp(x) * sigm(-x) -> sigm(x) exp(-x) * sigm(x) -> sigm(-x) """ def match(func, ops): # print [node.op.scalar_op for node in func.maker.fgraph.toposort()] assert [node.op for node in func.maker.fgraph.toposort()] == ops m = self.get_mode(excluding=["local_elemwise_fusion", "inplace"]) x, y = tensor.vectors("x", "y") f = theano.function([x], sigmoid(-x) * tensor.exp(x), mode=m) match(f, [sigmoid]) f = theano.function([x], sigmoid(x) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid]) f = theano.function([x], -(-(-(sigmoid(x)))) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid, tensor.neg]) f = theano.function( [x, y], (sigmoid(x) * sigmoid(-y) * -tensor.exp(-x) * tensor.exp(x * y) * tensor.exp(y)), mode=m ) match(f, [sigmoid, tensor.mul, tensor.neg, tensor.exp, sigmoid, tensor.mul])
def Generate_theta_p(x, s, I, N, K, prod_f): #print(s,N,len(x)) T = len(x) D = len(x[0]) s = [one_hot(ss, N) for ss in s] # x = [[xt for _ in range(N)] for xt in x] x = np.array(x) s = np.array(s) model = pm.Model() with model: # Priors for unknown model parameters theta = pm.Normal("theta", mu=0, sigma=1, shape=(D, K)) / np.sqrt( K * D) p_list = [] for t in range(T): #print(prod_f) #print(np.transpose(theta)) wt = dot(dot(prod_f, transpose(theta)), x[t]) swt = s[t] * wt sum_sw = sum(swt) p = exp(swt) / (1 + sum_sw) p0 = 1 / (1 + sum_sw) p_list.append(concatenate(([p0], p))) I_obs = pm.Categorical("I_obs", p=stack(p_list, axis=0), observed=I) with model: step = pm.Metropolis() trace1 = pm.sample(tune=2000, chains=1, step=step) return trace1["theta"][-1]
def test_local_sigm_times_exp(self): """ Test the `local_sigm_times_exp` optimization. exp(x) * sigm(-x) -> sigm(x) exp(-x) * sigm(x) -> sigm(-x) """ def match(func, ops): # print [node.op.scalar_op for node in func.maker.fgraph.toposort()] assert [node.op for node in func.maker.fgraph.toposort()] == ops m = self.get_mode(excluding=['local_elemwise_fusion', 'inplace']) x, y = tensor.vectors('x', 'y') f = theano.function([x], sigmoid(-x) * tensor.exp(x), mode=m) match(f, [sigmoid]) assert check_stack_trace(f, ops_to_check=sigmoid) f = theano.function([x], sigmoid(x) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid]) assert check_stack_trace(f, ops_to_check=sigmoid) f = theano.function([x], -(-(-(sigmoid(x)))) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid, tensor.neg]) # assert check_stack_trace(f, ops_to_check=sigmoid) f = theano.function([x, y], (sigmoid(x) * sigmoid(-y) * -tensor.exp(-x) * tensor.exp(x * y) * tensor.exp(y)), mode=m) topo = f.maker.fgraph.toposort() for op, nb in [(sigmoid, 2), (tensor.mul, 2), (tensor.neg, 1), (tensor.exp, 1)]: assert sum([n.op == op for n in topo]) == nb
def test_local_sigm_times_exp(self): """ Test the `local_sigm_times_exp` optimization. exp(x) * sigm(-x) -> sigm(x) exp(-x) * sigm(x) -> sigm(-x) """ def match(func, ops): # print [node.op.scalar_op for node in func.maker.fgraph.toposort()] assert [node.op for node in func.maker.fgraph.toposort()] == ops m = self.get_mode(excluding=['local_elemwise_fusion', 'inplace']) x, y = tensor.vectors('x', 'y') f = theano.function([x], sigmoid(-x) * tensor.exp(x), mode=m) match(f, [sigmoid]) f = theano.function([x], sigmoid(x) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid]) f = theano.function([x], -(-(-(sigmoid(x)))) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid, tensor.neg]) f = theano.function( [x, y], (sigmoid(x) * sigmoid(-y) * -tensor.exp(-x) * tensor.exp(x * y) * tensor.exp(y)), mode=m) match(f, [sigmoid, tensor.mul, tensor.neg, tensor.exp, sigmoid, tensor.mul])
def test_local_sigm_times_exp(self): """ Test the `local_sigm_times_exp` optimization. exp(x) * sigm(-x) -> sigm(x) exp(-x) * sigm(x) -> sigm(-x) """ def match(func, ops): # print [node.op.scalar_op for node in func.maker.fgraph.toposort()] assert [node.op for node in func.maker.fgraph.toposort()] == ops m = self.get_mode(excluding=['local_elemwise_fusion', 'inplace']) x, y = tensor.vectors('x', 'y') f = theano.function([x], sigmoid(-x) * tensor.exp(x), mode=m) match(f, [sigmoid]) assert check_stack_trace(f, ops_to_check=sigmoid) f = theano.function([x], sigmoid(x) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid]) assert check_stack_trace(f, ops_to_check=sigmoid) f = theano.function([x], -(-(-(sigmoid(x)))) * tensor.exp(-x), mode=m) match(f, [tensor.neg, sigmoid, tensor.neg]) # assert check_stack_trace(f, ops_to_check=sigmoid) f = theano.function( [x, y], (sigmoid(x) * sigmoid(-y) * -tensor.exp(-x) * tensor.exp(x * y) * tensor.exp(y)), mode=m) topo = f.maker.fgraph.toposort() for op, nb in [(sigmoid, 2), (tensor.mul, 2), (tensor.neg, 1), (tensor.exp, 1)]: assert sum([n.op == op for n in topo]) == nb
def local_exp_over_1_plus_exp(node): """ exp(x)/(1+exp(x)) -> sigm(x) c/(1+exp(x)) -> c*sigm(-x) """ # this optimization should be done for numerical stability # so we don't care to check client counts if node.op == tensor.true_div: # find all the exp() terms in the numerator num, denom = node.inputs num_exp_x, num_rest, num_neg = partition_num_or_denom(num, is_exp) denom_1pexp, denom_rest, denom_neg = partition_num_or_denom( denom, is_1pexp) sigmoids = [] for t in denom_1pexp: if t in num_exp_x: # case: exp(x) /(1+exp(x)) sigmoids.append(sigmoid(t)) del num_exp_x[num_exp_x.index(t)] else: # case: 1/(1+exp(x)) sigmoids.append(sigmoid(-t)) copy_stack_trace(node.outputs[0], sigmoids[-1]) if not sigmoids: # we didn't find any. abort return # put the new numerator together new_num = sigmoids + [tensor.exp(t) for t in num_exp_x] + num_rest if len(new_num) == 1: new_num = new_num[0] else: new_num = tensor.mul(*new_num) if num_neg ^ denom_neg: new_num = -new_num copy_stack_trace(num, new_num) if len(denom_rest) == 0: return [new_num] elif len(denom_rest) == 1: out = new_num / denom_rest[0] else: out = new_num / tensor.mul(*denom_rest) copy_stack_trace(node.outputs[0], out) return [out]
def local_exp_over_1_plus_exp(node): """ exp(x)/(1+exp(x)) -> sigm(x) c/(1+exp(x)) -> c*sigm(-x) """ # this optimization should be done for numerical stability # so we don't care to check client counts if node.op == tensor.true_div: # find all the exp() terms in the numerator num, denom = node.inputs num_exp_x, num_rest, num_neg = partition_num_or_denom(num, is_exp) denom_1pexp, denom_rest, \ denom_neg = partition_num_or_denom(denom, is_1pexp) sigmoids = [] for t in denom_1pexp: if t in num_exp_x: # case: exp(x) /(1+exp(x)) sigmoids.append(sigmoid(t)) del num_exp_x[num_exp_x.index(t)] else: # case: 1/(1+exp(x)) sigmoids.append(sigmoid(-t)) copy_stack_trace(node.outputs[0], sigmoids[-1]) if not sigmoids: # we didn't find any. abort return # put the new numerator together new_num = sigmoids + [tensor.exp(t) for t in num_exp_x] + num_rest if len(new_num) == 1: new_num = new_num[0] else: new_num = tensor.mul(*new_num) if num_neg ^ denom_neg: new_num = -new_num copy_stack_trace(num, new_num) if len(denom_rest) == 0: return [new_num] elif len(denom_rest) == 1: out = new_num / denom_rest[0] else: out = new_num / tensor.mul(*denom_rest) copy_stack_trace(node.outputs[0], out) return [out]