def set_params(self, *, params: Params) -> None: full_weights = np.append(params['weights'], params['offset']) self._weights = to_variable(full_weights, requires_grad=True) self._weights.retain_grad() self._weights_variance = to_variable(params['weights_variance'], requires_grad=True) self._noise_variance = to_variable(params['noise_variance'], requires_grad=True) self.label_name_columns = params['target_names_'] self._fitted = True
def gradient_output(self, *, outputs: Outputs, inputs: Inputs) -> Gradients[Outputs]: # type: ignore """ Calculates grad_output log normal_density(self.weights * self.input - output, identity * self.noise_variance) for a single input/output pair. """ inputs = self._offset_input(inputs=inputs) outputs_vars = [ to_variable(output, requires_grad=True) for output in outputs ] inputs_vars = [to_variable(input) for input in inputs] grad = sum( self._gradient_output_log_likelihood(output=output, input=input) for (input, output) in zip(inputs_vars, outputs_vars)) return grad.data.numpy()
def log_likelihoods(self, *, outputs: Outputs, inputs: Inputs, timeout: float = None, iterations: int = None) -> CallResult[ndarray]: """ input : D-length numpy ndarray output : float Calculates log(normal_density(self.weights * self.input - output, identity * self.noise_variance)) for a single input/output pair. """ result = np.array([ self._log_likelihood(output=to_variable(output), input=to_variable(input)).data.numpy() for input, output in zip(inputs, outputs) ]) return CallResult(result)
def produce(self, *, inputs: Inputs, timeout: float = None, iterations: int = None) -> CallResult[Outputs]: """ inputs: (num_inputs, D) numpy array outputs : numpy array of dimension (num_inputs) """ # Curate data XTest, feature_columns = self._curate_data(training_inputs=inputs, training_outputs=None, get_labels=False) XTest = self._offset_input(inputs=XTest) self._weights = refresh_node(self._weights) self._noise_variance = refresh_node(self._noise_variance) self._weights_variance = refresh_node(self._weights_variance) self._inputs = to_variable(XTest, requires_grad=True) mu = torch.mm(self._inputs, self._weights.unsqueeze(0).transpose(0, 1)).squeeze() reparameterized_normal = torch.distributions.normal.Normal( mu, self._noise_variance.expand(len(mu))) self._outputs = reparameterized_normal.rsample() self._outputs.reqiures_grad = True predictions = self._outputs.data.numpy() # Delete columns with path names of nested media files outputs = inputs.remove_columns(feature_columns) # Convert from ndarray from DataFrame predictions = container.DataFrame(predictions, generate_metadata=True) # Update Metadata for each feature vector column for col in range(predictions.shape[1]): col_dict = dict( predictions.metadata.query((metadata_base.ALL_ELEMENTS, col))) col_dict['structural_type'] = type(1.0) col_dict['name'] = self.label_name_columns[col] col_dict["semantic_types"] = ( "http://schema.org/Float", "https://metadata.datadrivendiscovery.org/types/PredictedTarget", ) predictions.metadata = predictions.metadata.update( (metadata_base.ALL_ELEMENTS, col), col_dict) # Rename Columns to match label columns predictions.columns = self.label_name_columns # Append to outputs outputs = outputs.append_columns(predictions) return base.CallResult(outputs)
def _gradient_output_log_likelihood( self, *, output: ndarray, input: torch.autograd.Variable) -> torch.autograd.Variable: """ output is D-length torch variable """ output_var = to_variable(output) log_likelihood = self._log_likelihood(output=output_var, input=input) log_likelihood.backward() return output_var.grad
def set_training_data(self, *, inputs: Inputs, outputs: Outputs) -> None: inputs, outputs, _ = self._curate_data(training_inputs=inputs, training_outputs=outputs, get_labels=True) N, P = inputs.shape if self._use_gradient_fit: self._use_analytic_form = False elif P < N and N / P < self._analytic_fit_threshold: self._use_analytic_form = True inputs_with_ones = np.insert(inputs, P, 1, axis=1) self._training_inputs = to_variable(inputs_with_ones, requires_grad=True) self._training_outputs = to_variable(outputs, requires_grad=True) self._new_training_data = True self._has_finished = False self._iterations_done = 0 self._converged_count = 0 self._best_rmse = np.inf
def _log_likelihood( self, output: torch.autograd.Variable, input: torch.autograd.Variable) -> torch.autograd.Variable: """ All inputs are torch tensors (or variables if grad desired). input : D-length torch to_variable output : float """ expected_output = torch.dot(self._weights, input).unsqueeze(0) covariance = to_variable(self._noise_variance).view(1, 1) return log_mvn_likelihood(expected_output, covariance, output)
def gradient_params(self, *, outputs: Outputs, inputs: Inputs) -> Gradients[Params]: # type: ignore """ Calculates grad_weights fit_term_temperature * log normal_density(self.weights * self.input - output, identity * self.noise_variance) for a single input/output pair. """ outputs_vars = [ to_variable(output, requires_grad=True) for output in outputs ] inputs_vars = [to_variable(input) for input in inputs] grads = [ self._gradient_params_log_likelihood(output=output, input=input) for (input, output) in zip(inputs_vars, outputs_vars) ] grad_weights = sum(grad[0] for grad in grads) grad_noise_variance = sum(grad[1] for grad in grads) return Params(weights=grad_weights, offset=grad_offset, noise_variance=grad_noise_variance)