def sample(self, device, epoch, num=64): sample = torch.randn(num, self.latent_dim).to(device) x_alpha, x_beta = self.decode(sample) beta = Beta(x_alpha, x_beta) p = beta.sample() binomial = Binomial(255, p) x_sample = binomial.sample() x_sample = x_sample.float() / 255. save_image(x_sample.view(num, 1, 28, 28), 'results/epoch_{}_samples.png'.format(epoch))
def one_hot_indices(batch_size, num_classes, input_size, max_rois): torch.random.manual_seed(42) height, width = input_size if batch_size is not None: out_shape = (batch_size, num_classes, height, width) else: out_shape = (num_classes, height, width) d = Binomial(1, torch.tensor([max_rois / (height * width)])) return d.sample(out_shape).squeeze(-1).bool()
def reconstruct(self, x, device, epoch): x = x.view(-1, 784).float().to(device) z_mu, z_logvar = self.encode(x) z = self.reparameterize(z_mu, z_logvar) # sample zs x_alpha, x_beta = self.decode(z) beta = Beta(x_alpha, x_beta) p = beta.sample() binomial = Binomial(255, p) x_recon = binomial.sample() x_recon = x_recon.float() / 255. x_with_recon = torch.cat((x, x_recon)) save_image(x_with_recon.view(64, 1, 28, 28), 'results/epoch_{}_recon.png'.format(epoch))
def prop_state(x, f, g): bins = Independent(Binomial(x[:-1], f), 1) samp = bins.sample() s = x[0] - samp[..., 0] i = x[1] + samp[..., 0] - samp[..., 1] r = x[2] + samp[..., 1] return concater(s, i, r)
def test_StochasticSIR(self): dist = Independent( Binomial(torch.tensor([1000, 1, 0]), torch.tensor([1, 1, 1e-6])), 1) sir = m.StochasticSIR((0.1, 0.05, 0.01), dist, 1e-1) x = sir.sample_path(1000, 10) self.assertEqual(x.shape, torch.Size([1000, 10, 3]))
def update_nois(self): ns_additional_rewards = torch.ceil(self.arm_counter * self.pseudo_rewards_per_timestep) distr = Binomial(ns_additional_rewards, torch.ones_like(ns_additional_rewards) * 0.5) sampled_sums_01 = distr.sample() / ns_additional_rewards # Normalize the samples from the binomial distribution into the appropriate range min_s, max_s = self.return_range[ 0] * ns_additional_rewards, self.return_range[ 1] * ns_additional_rewards sampled_sums = sampled_sums_01 * (max_s - min_s) + min_s denominator = self.arm_counter + ns_additional_rewards numerator = self.arm_cumulative_payoff + sampled_sums average_returns = numerator / denominator # Select current policy self.current_policy_index = average_returns.argmax().item()
def mixed_simulator(theta): # Extract parameters beta, ps = theta[:, :1], theta[:, 1:] # Sample choices and rts independently. choices = Binomial(probs=ps).sample() rts = InverseGamma(concentration=2 * torch.ones_like(beta), rate=beta).sample() return torch.cat((rts, choices), dim=1)
def prop_state(x, beta, gamma, eta, dt): f = _f(x, beta, gamma, eta, dt) bins = Independent(Binomial(x[..., :-1], f), 1) samp = bins.sample() s = x[..., 0] - samp[..., 0] i = x[..., 1] + samp[..., 0] - samp[..., 1] r = x[..., 2] + samp[..., 1] return concater(s, i, r)
def update_randomist(self): returns = torch.tensor(list(zip(*self.buffer))[-1]) importance_weights, exp_renyi_divergences = self.compute_importance_weights( self_normalize=False, renyi_alpha=1 + self.eps) # shape: (n_policies, n_returns), (n_policies,) ess = self.t / (exp_renyi_divergences) ns_additional_rewards = torch.ceil(ess * self.pseudo_rewards_per_timestep) distr = Binomial(ns_additional_rewards, torch.ones_like(ns_additional_rewards) * 0.5) sampled_sums_01 = distr.sample() / ns_additional_rewards # Normalize the samples from the binomial distribution into the appropriate range min_s, max_s = self.return_range[ 0] * ns_additional_rewards, self.return_range[ 1] * ns_additional_rewards U = sampled_sums_01 * (max_s - min_s) + min_s eta = U / ns_additional_rewards bias_correction = torch.sqrt((self.alpha * math.log(self.t)) / ess) eta = eta + bias_correction # Clip weights thresholds = torch.sqrt( (exp_renyi_divergences * self.t) / (self.alpha * math.log(self.t))) thresholds = thresholds.view(-1, 1).expand_as(importance_weights) importance_weights = torch.where(importance_weights > thresholds, thresholds, importance_weights) # MIST estimator mu = torch.sum(importance_weights * returns, dim=-1) bias_correction = (self.return_range[1] - self.return_range[0]) * ( (self.alpha * exp_renyi_divergences * math.log(self.t)) / self.t)**(self.eps / (1 + self.eps)) # Compute average returns average_returns = mu + eta + bias_correction # Select current policy self.current_policy_index = average_returns.argmax().item()
def train_pg(self, state, action, reward): """ Train the policy using a policy gradient approach :param state: the input state(s) :param action: the input action(s) :param reward: the resulting reward :return: the loss applied to train the policy """ action = torch.FloatTensor(action) reward = torch.FloatTensor(reward) pred = self.forward(state) m = Binomial(pred, action) loss = -m * reward # Negative score function x reward self.update(loss) return loss
def get_distribution_of_true_labels(self, labels, p_Q_given_x, distr_params): """ For each expert i, returns the probability associated to a specific label. """ eps = 1e-12 if 'binomial' in self.output_type: n, p = distr_params # Assume 1 for now if len(n.shape) == 2: n = n.unsqueeze(2) # add output feature dim # distr_params is now [samples, no_experts, 1=no_features] if len(p.shape) == 2: p = p.unsqueeze(2) # add output feature dim mix = Categorical(p_Q_given_x) comp = Independent(Binomial(n, p), 1) pmm = MixtureSameFamily(mix, comp) if len(labels.shape) == 1: labels = labels.unsqueeze(1) # add output feature dim x = pmm._pad(labels) emission_of_true_labels = pmm.component_distribution.log_prob( x.float()).exp() + eps # [samples, experts] elif 'gaussian' in self.output_type: mu, var = distr_params mix = Categorical(p_Q_given_x) comp = Independent( Normal(loc=mu, scale=var), 1) # mu/var have shape [samples, experts, features] gmm = MixtureSameFamily(mix, comp) # labels has shape [samples, features] x = gmm._pad(labels) emission_of_true_labels = gmm.component_distribution.log_prob( x).exp() # [samples, experts], one prob for each expert return emission_of_true_labels
def iid_likelihood(self, theta: torch.Tensor) -> torch.Tensor: """Returns the likelihood summed over a batch of i.i.d. data.""" lp_choices = torch.stack( [ Binomial(probs=th.reshape(1, -1)).log_prob(self.x_o[:, 1:]) for th in theta[:, 1:] ], dim=1, ) lp_rts = torch.stack( [ InverseGamma(concentration=2 * torch.ones_like(beta_i), rate=beta_i).log_prob(self.x_o[:, :1]) for beta_i in theta[:, :1] ], dim=1, ) joint_likelihood = (lp_choices + lp_rts).reshape( self.x_o.shape[0], theta.shape[0]) return joint_likelihood.sum(0)
def forward(self, x): if self.p == 0 or not self.training: return x if self.dropout_fixed and self.training: self.dindexes = self.dindexes.to(x.device) assert len(x.size()) == 3, ( "Expected to get 3 dimensional tensor, got {}"\ .format(len(x.size())) ) bsize, emb_size, tsize = x.size() #print (bsize, esize, tsize) if self.drop_whole_channels: batch_mask = torch.full(size=(bsize, emb_size), fill_value=1.0, device=x.device) probs = torch.full(size=(bsize, self.dropped_dimsize), fill_value=1. - self.p) b = Binomial(total_count=1, probs=probs) mask = b.sample() mask = mask.to(x.device) batch_mask[:, self.dindexes] *= (mask * self.p_scale) #print ('mask dc', mask) #print ('maks dcv', mask.view(bsize, self.dropped_dimsize, -1)) #x[:,self.dindexes,:] = x[:,self.dindexes,:].clone() * self.p_scale\ # * mask.view(bsize, self.dropped_dimsize, -1) x = x * batch_mask.view(bsize, emb_size, -1) else: batch_mask = torch.ones_like(x, device=x.device) probs = torch.full(size=(bsize, self.dropped_dimsize, tsize), fill_value=1. - self.p) b = Binomial(total_count=1, probs=probs) mask = b.sample() mask = mask.to(x.device) batch_mask[:, self.dindexes, :] *= (mask * self.p_scale) x = x * batch_mask #xx = x.data.clone() #x[:,self.dindexes,:] = x[:,self.dindexes,:].clone() * mask * self.p_scale return x else: return F.dropout(x, p=self.p, training=self.training)
def approximate_shap_values(self, input_ids, attention_mask, user_id): """ main method to compute SHAP values for each feature specified by tweet input and user input :param input_ids: from BERT :param attention_mask: from BERT :param user_id: identifies user specific information :return: shapley_values: Matrix containing the shapley values for all features and each class :return: max_pred.item(): Class predicted by the model :return: [words_in_tweet, vocab_features, network_features]: Feature distribution :return: vocab_indices: Indices of the vocabulary of the user in the vocabulary dictionary """ self.model_to_explain.eval() prediction = self.model_to_explain(input_ids, attention_mask, user_id) prediction = torch.nn.functional.softmax(prediction) max_pred = torch.argmax(prediction) #tweet feature initialisation if self.tweet_as_one == False: words_in_tweet = attention_mask.sum().item( ) - 2 # the -2 is for eliminating the CLS and SEP token else: words_in_tweet = 1 #vocabulary feature initialisation if self.vocab_as_one == True: vocab_features = 1 adjusted_user_vocab = None vocab_indices = None else: user_vocab = self.model_to_explain.BOW(user_id) vocab_features = user_vocab.sum(dtype=torch.int32).item() vocab_indices = torch.nonzero(user_vocab) set_BOW_to_NULL = False #network feature initialisation if self.network_as_one == True: network_features = 1 else: user_dictionary = self.community_dictionary[str(user_id.item())] count_com_relations = len(user_dictionary["communities"]) if count_com_relations > 0: network_features = count_com_relations else: network_features = 1 set_Tweet_to_NULL = False no_of_features = words_in_tweet + vocab_features + network_features shapley_values = torch.zeros( (self.APPROX_LEVEL, no_of_features, self.classes)) for trial in range(self.APPROX_LEVEL): # sampling for feature permutations feature_subset = Binomial(1, torch.tensor( [self.P] * no_of_features)).sample() for feature in range(no_of_features): #compute prediction with feature included helper = feature_subset[feature].item() feature_subset[feature] = 1 if self.tweet_as_one == False: adjusted_mask = self.subsetting_attention_mask( attention_mask, feature_subset) else: adjusted_mask = attention_mask.clone().detach() if feature_subset[0] == 0: set_Tweet_to_NULL = True else: set_Tweet_to_NULL = False if self.vocab_as_one == True: if feature_subset[-(network_features + 1)] == 0: set_BOW_to_NULL = True else: set_BOW_to_NULL = False else: adjusted_user_vocab = self.subsetting_user_vocab( user_vocab, vocab_indices, feature_subset, words_in_tweet) if self.network_as_one == True: nodes_to_delete_in_SHAP = None if feature_subset[-1] == 0: set_GRAPH_to_NULL = True else: set_GRAPH_to_NULL = False else: set_GRAPH_to_NULL = False if count_com_relations > 0: nodes_to_delete_in_SHAP = self.list_user_relationships_to_delete( user_dictionary, feature_subset[-count_com_relations:]) else: nodes_to_delete_in_SHAP = None prediction_with = self.model_to_explain( input_ids, adjusted_mask, user_id, True, self.vocab_as_one, set_Tweet_to_NULL, set_BOW_to_NULL, set_GRAPH_to_NULL, adjusted_user_vocab, nodes_to_delete_in_SHAP) prediction_with = torch.nn.functional.softmax(prediction_with) #compute prediction without feature included feature_subset[feature] = 0 if self.tweet_as_one == False: adjusted_mask = self.subsetting_attention_mask( attention_mask, feature_subset) else: adjusted_mask = attention_mask.clone().detach() if feature_subset[0] == 0: set_Tweet_to_NULL = True else: set_Tweet_to_NULL = False if self.vocab_as_one == True: if feature_subset[-(network_features + 1)] == 0: set_BOW_to_NULL = True else: set_BOW_to_NULL = False else: adjusted_user_vocab = self.subsetting_user_vocab( user_vocab, vocab_indices, feature_subset, words_in_tweet) if self.network_as_one == True: nodes_to_delete_in_SHAP = None if feature_subset[-1] == 0: set_GRAPH_to_NULL = True else: set_GRAPH_to_NULL = False else: set_GRAPH_to_NULL = False if count_com_relations > 0: nodes_to_delete_in_SHAP = self.list_user_relationships_to_delete( user_dictionary, feature_subset[-count_com_relations:]) else: nodes_to_delete_in_SHAP = None prediction_without = self.model_to_explain( input_ids, adjusted_mask, user_id, True, self.vocab_as_one, set_Tweet_to_NULL, set_BOW_to_NULL, set_GRAPH_to_NULL, adjusted_user_vocab, nodes_to_delete_in_SHAP) prediction_without = torch.nn.functional.softmax( prediction_without) #prediction with and without return array of length three (for the respective number of classes) shapley_values[trial][ feature] = prediction_with - prediction_without feature_subset[feature] = helper shapley_values = shapley_values.mean(axis=0).T return shapley_values, max_pred.item(), [ words_in_tweet, vocab_features, network_features ], vocab_indices
### 分配物件之基礎 `torch.distribution` 內建了許多機率分配物件(見[官方網頁](https://pytorch.org/docs/stable/distributions.html)),而分配物件可供使用者 1. 產生隨機樣本。 2. 給定實現值計算可能性或機率值。 2. 給定上界計算累積機率值(並非每個分配都可以)。 在產生一分配物件時,我們需給定該分配的參數。以常態分配為例,其參數包括了平均數與變異數,此兩參數亦稱作位置(location)參數與尺度(scale)參數 from torch.distributions import Normal normal = Normal(loc=0., scale=1.) 再以Binomial分配為例,其參數為嘗試次數與成功之機率(也可以使用對數勝率來設定) from torch.distributions import Binomial binomial = Binomial(total_count = 10, probs = 0.5) 我們可以透過對分配物件的列印,以了解其內部之參數設定: print(normal) print(binomial) 對於已建立之分配物件,我們可以利用其`.sample()`方法來產生隨機變數 print("random sample with shape ():\n", normal.sample()) print("random sample with shape (3,):\n", normal.sample(sample_shape=(3,))) print("random sample with shape (2,3):\n", normal.sample(sample_shape=(2, 3)))