def _sparsify(self, sparsity_type, epsilon=0.01): sparse_vector = self._params[str(sparsity_type) + "_sparsity_vector"] sparse_vector = sparse_vector - sparse_vector.mean() sparse_vector = sparse_vector * (sparse_vector.var() + epsilon) sparse_vector = sparse_vector * torch.exp( self._params[str(sparsity_type) + "_sparsity_coef"]) return torch.sigmoid(sparse_vector)
def predict(self, img, model, gpu_arg, topk=5): """ Predicts the class (or classes) of an image using a trained deep learning model. INPUTS: 1. Numpy image array 2. Network model <model object> 3. GPU user selection: <bool> 4. Requested top K results: <int> RETURNS: 1. List of top K probabilities: <list> 2. List of top K classes: <list> """ # Predict the class from an image file # push model to correct processor device = self.gpu_status(gpu_arg) model.to(device) # turn off gradient calc for testing model.eval() with torch.no_grad(): # send image to correct environment (GPU vs CPU) and # perform a forward pass logps = model.forward(img.to(device)) # get the log softmax values and convert to probabilities probs = torch.exp(logps) # convert to the top (k) labels probs, classes = probs.topk(topk) return probs.tolist()[0], classes.tolist()[0]
def _inversion_forward(self, constants, feature_sparsity): X, y, XTX, XTy = constants.values() if feature_sparsity: sparse_vector = torch.diag(self._sparsify("feature")) sparse_X = X @ sparse_vector sparse_XTX = sparse_vector @ XTX @ sparse_vector sparse_XTy = sparse_vector @ XTy penality = torch.exp(self._params["lambda"]) * torch.diag( torch.ones(XTX.shape[0])).float().cuda() inv = torch.inverse(sparse_XTX + penality) projection_matrix = sparse_X @ inv y_hat = projection_matrix @ sparse_XTy return y_hat, permuted_y_hat else: penality = torch.exp(self._params["lambda"]) * torch.diag( torch.ones(XTX.shape[0])).float().cuda() inv = torch.inverse(XTX + penality) projection_matrix = X @ inv y_hat = projection_matrix @ XTy return y_hat
def _inversion_coef(self, constants): X, y, permuted_y, XTX, XTy, XTmy = constants.values() feature_sparsity = self.feature_sparsity if self.GPU: identity = torch.diag(torch.ones(XTX.shape[0])).float().cuda() else: identity = torch.diag(torch.ones(XTX.shape[0])).float() penality = torch.exp(self._params["lambda"]) * identity if self.elastic_feature_sparsity: mu = torch.sigmoid(self._params["feature_elastic_coef"]) coef = self._inversion_coef_without_sparsity(penality, XTX, XTy) * mu coef += self._inversion_coef_with_sparsity(penality, XTX, XTy) * (1 - mu) elif feature_sparsity: coef = self._inversion_coef_with_sparsity(penality, XTX, XTy) else: coef = self._inversion_coef_without_sparsity(penality, XTX, XTy) self.coef_ = self._tensor_to_array(coef)
def _get_diag(self, eigen, epsilon=1e-8): penality = torch.exp(self._params["lambda"]) return (eigen + penality + epsilon)**(-1)
def train_network(self, gpu_arg, model, optimizer, criterion, epochs=1, top_k=1): """ Performs training of the network's features only along with validation accuracy and loss rates while conducting the training operation. INPUTS: 1. GPU user selection: <bool> 2. Network model: <model object> 3. Gradient descent def: <optimizer object> 4. Predefined loss def: <criterion object> 5. User's epoch value: <int> 6. Top K id's for error: <int> RETURNS: None """ # update the requested epochs value self.epochs = epochs # push model to correct processor device = self.gpu_status(gpu_arg) model.to(device) # now for the training and validation process print(f"Training the model with the following parameters:\n" f"\tmodel archit.: \t{self.arch}\n" f"\thidden units: \t{self.hidden_size}\n" f"\tlearning rate: \t{self.learning_rate}\n" f"\ttotal epochs: \t{self.epochs}\n" f"\tGPU processing: \t{self.device_location.upper()}\n" ) print("Starting epoch: 1 of {}...".format(self.epochs)) # loop thru based on total epochs desired for epoch in range(self.epochs): # reset loss and accuracy counters for each new epoch self.training_loss = 0 valid_loss = 0 valid_accuracy = 0 # train the model with the training data model.train() for inputs, labels in self.train_loader: # forward pass with inputs and labels to correct environment (GPU vs CPU) inputs, labels = inputs.to(device), labels.to(device) # turn off gradient optimizer.zero_grad() # use network outputs to calculate loss log_ps = model.forward(inputs) loss = criterion(log_ps, labels) # perform backward pass to calc gradients and take step to update weights loss.backward() optimizer.step() self.training_loss += loss.item() else: # evaluate the model with the validation data # turn off gradient calc for validation model.eval() with torch.no_grad(): # test the model with the validation data for inputs, labels in self.valid_loader: # send inputs and labels to correct environment (GPU vs CPU) inputs, labels = inputs.to(device), labels.to(device) # perform a forward pass & get loss rate for batch logps = model.forward(inputs) batch_loss = criterion(logps, labels) # accumulate validation total loss from current batch valid_loss += batch_loss.item() # Calculate accuracy values ps = torch.exp(logps) _, top_class = ps.topk(top_k, dim=1) equals = top_class == labels.view(*top_class.shape) valid_accuracy += torch.mean(equals.type(torch.FloatTensor)).item() # output the results as we go to watch for productive progress print(f"Epoch {epoch + 1} / {self.epochs}.. " f"Train loss: {self.training_loss / len(self.train_loader):.3f}.. " f"Valid loss: {valid_loss / len(self.valid_loader):.3f}.. " f"Valid accuracy: {valid_accuracy / len(self.valid_loader):.2f}")