def main(): user_input = get_input_args() image_datasets, dataloaders = utilfunc.create_dataloaders( user_input.data_dir) model = modfunc.create_model(user_input.arch, output_size=user_input.outsize, change_classifier=user_input.change_class, nodes_per_hlayer=user_input.npl) optimizer = optim.Adam(model.classifier.parameters(), lr=user_input.lr) criterion = nn.NLLLoss() network_training(model=model, dataloaders=dataloaders, epochs=user_input.epochs, learning_rate=user_input.lr, with_gpu=user_input.gpu) modfunc.save_checkpoint(filename=user_input.save_dir, model=model, image_datasets=image_datasets, architecture=user_input.arch, output_size=user_input.outsize, hidden_layers=user_input.npl, learning_rate=user_input.lr, optimizer=optimizer, epochs=user_input.epochs)
if steps % print_every == 0: # change model to evaluation mode model.eval() # perform validation steps with torch.no_grad(): valid_loss, accuracy = validation(model, criterion, validloader) print('Epoch {}/{}'.format(e+1, epochs)) print('Training loss: {:.4f}'.format(running_loss/print_every)) print('Validation loss: {:.4f}'.format(valid_loss/len(validloader))) print('Validation accuracy: {:.4f}%'.format((accuracy/len(validloader))*100)) running_loss = 0 # change model back to training mode model.train() # set class_to_idx mapping for model model.class_to_idx = train_dataset.class_to_idx # save model checkpoint if args['save_dir'] is None: save_filepath = data_dir + '/checkpoint.pth' else: save_filepath = args['save_dir'] + '/checkpoint.pth' save_checkpoint(model, arch, optimizer, epochs, input_size, output_size, hidden_units, save_filepath)
if arguments.gpu: device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") else: device = "cpu" #load datasets loaded_datasets = load_datasets(arguments.dir) #create the model model = create_model(loaded_datasets['image_datasets'], arguments.arch, arguments.hidden_units) #train the model criterion = nn.NLLLoss() optimizer = optim.Adam(model.classifier.parameters(), lr=arguments.learning_rate) train_network(loaded_datasets['dataloaders'], model, criterion, optimizer, arguments.epochs, device) #save trained model save_checkpoint(criterion, arguments.epochs, optimizer, model, arguments.arch, arguments.save_dir) # print("Command Line Arguments:\n dir =", arguments.dir, # "\n arch =", arguments.arch, # "\n learning_rate =", arguments.learning_rate, # "\n hidden_units =", arguments.hidden_units, # "\n gpu =", arguments.gpu, # "\n epochs =", arguments.epochs, # "\n save_dir =", arguments.save_dir)
# We want to ensure the final layers are consistent with our problem by using an ordered dictionary. classifier = nn.Sequential(OrderedDict([('fc1', nn.Linear(input_size, arguments.num_hidden)), # Number of neurons in the hidden layer ('relu', nn.ReLU()), # ReLU activation function will squish the output space of the previous layer ('drop', nn.Dropout(p=0.5)), # Used to prevent overfitting - for any node in the network this will equate to 50% chance it will be randomly turned off ('fc2', nn.Linear(arguments.num_hidden, 102)), # Input 5000, Output layer of 102 ('output', nn.LogSoftmax(dim=1))])) # Squishes the output space to be between 0 - 1 i.e. probability of class assignment for each image. Ideal for multiclass problems # Ensure we overwrite the model classifier with the newly configured ordered dictionary model.classifier = classifier # Setting up the model input arguments (hyperparameters) # Model, criterion, optimizer, scheduler, num_epochs=25, device='cuda' # Model is initialised in block above to pretrained vgg16 with classifier adjusted # Criteria here represents the loss function used to evaluate the model fit # NLLLoss which is recommended with Softmax final layer criteria = nn.NLLLoss() # Observe that all parameters are being optimized with a learning rate of 0.001 for gradient descent optim = torch.optim.Adam(model.classifier.parameters(), arguments.learning_rate) # Provides different methods for adjusting the learning rate and step size used during optimisation # Decay LR by a factor of 0.1 every 3 epochs sched = lr_scheduler.StepLR(optim, step_size=arguments.step_size_sched, gamma=arguments.gamma_lrsched) model_functions.train_model(model, criteria, optim, sched, arguments.epochs, dataset_sizes, data_loaders, arguments.device) model_functions.test_acc(model, data_loaders, arguments.device) model_functions.save_checkpoint(model, optim, image_datasets, arguments.arch, arguments.epochs, arguments.learning_rate, input_size, arguments.num_hidden)
torch.FloatTensor)).item() print( f"Epoch {epoch+1}/{epochs}.. " f"Train loss: {running_loss/print_every:.3f}.. " f"Validation loss: {validation_loss/len(validloader):.3f}.. " f"Validation accuracy: {100*accuracy/len(validloader):.3f}" ) running_loss = 0 model.train() print('Training complete.') ##### Save checkpoint #if args.save_dir not in os.listdir(): if not os.path.isdir(args.save_dir): os.mkdir(args.save_dir) save_checkpoint(model, train_dataset, h_units[0], h_units[1], h_units[2], h_units[3], h_units[4], epochs, learn, optimizer, criterion, filename=args.save_dir + '/0502_densenet161_ams.pth', arch=arch)
model = models.alexnet(pretrained=True) print(model) # Freeze pretrained model parameters to avoid backpropogating through them for parameter in model.parameters(): parameter.requires_grad = False # Build custom classifier classifier = nn.Sequential(OrderedDict([('fc1', nn.Linear(input_size, arguments.hidden_units)), ('relu', nn.ReLU()), ('drop', nn.Dropout(p=0.5)), ('fc2', nn.Linear(arguments.hidden_units, 11)), ('output', nn.LogSoftmax(dim=1))])) model.classifier = classifier # Loss function (since the output is LogSoftmax, we use NLLLoss) criterion = nn.NLLLoss() # Gradient descent optimizer optimizer = optim.Adam(model.classifier.parameters(), lr=arguments.learning_rate) model_functions.train_classifier(model, optimizer, criterion, arguments.epochs, train_loader, validate_loader, arguments.gpu) model_functions.test_accuracy(model, test_loader, arguments.gpu) model_functions.save_checkpoint(model, training_dataset, arguments.arch, arguments.epochs, arguments.learning_rate, arguments.hidden_units, input_size)
def main(): # Parse the arguments passed by the user parsed_arguments = arg_parser() # Define train, test and validation directories based on the data directory passed by the user. # Check if those directories exist. If not break the program. if (os.path.isdir(parsed_arguments.data_directory + "/test") and os.path.isdir(parsed_arguments.data_directory + "/train") and os.path.isdir(parsed_arguments.data_directory + "/valid")): data_dir = parsed_arguments.data_directory train_dir = data_dir + '/train' valid_dir = data_dir + '/valid' test_dir = data_dir + '/test' # Create a transforms for the specific directory train_transform = data_functions.create_transform(train_dir) valid_transform = data_functions.create_transform(valid_dir) test_transform = data_functions.create_transform(test_dir) # Create dataloader for the data sets trainloader = data_functions.define_dataloader(train_dir, train_transform) validloader = data_functions.define_dataloader(valid_dir, valid_transform) testloader = data_functions.define_dataloader(test_dir, test_transform) # Create a mapping from category label to category name cat_to_name = data_functions.label_mapping('cat_to_name.json') # Load a pretrained model according to architecture given by the user model = model_functions.load_pretrained_model(parsed_arguments.arch) # Freeze parameters in the model for param in model.parameters(): param.requires_grad = False # Define a new classifier new_classifier = model_functions.create_new_classifier( model.classifier[0].in_features, parsed_arguments.hidden_units) # Replace the model classifier model.classifier = new_classifier # Define criterion and optimizer criterion = nn.NLLLoss() optimizer = optim.Adam(model.classifier.parameters(), lr=0.00075) # Use proper device (cpu/gpu) device = torch.device("cuda:0" if ( torch.cuda.is_available() and parsed_arguments.gpu) else "cpu") print(device) model.to(device) # Train the network model = model_functions.train_network(model, trainloader, validloader, optimizer, criterion, parsed_arguments.epochs, device) # Validate the network #validation_accuracy = model_functions.network_accuracy(model, validloader, device) #print('Accuracy on the validation images: %d %%' % validation_accuracy) # Check accuracy on the test dataset training_accuracy = model_functions.network_accuracy( model, testloader, device) print('Accuracy on the test images: %d %%' % training_accuracy) # Save the checkpoint model.class_to_idx = datasets.ImageFolder( train_dir, transform=train_transform).class_to_idx model_functions.save_checkpoint(model, parsed_arguments.arch, model.classifier[0].in_features, parsed_arguments.hidden_units, parsed_arguments.save_dir, parsed_arguments.gpu) else: print("Could not find test, train or valid folder inside of %s", parsed_arguments.data_directory) return
def main(): # Get command line input arguments in_arg = get_input_args() # Load data train_loader, valid_loader, test_loader, train_data = model_functions.load_data(in_arg.data_dir) # Define Learning Rate learn_rate = in_arg.learning_rate # Use GPU if available device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = models.densenet121(pretrained=True) # Download the model # Freeze parameters in model feature so we don't backprop through them for param in model.parameters(): param.requires_grad = False # Create an instance of the Classifier object model.classifier = Classifier() # Create an instance of the Loss object criterion = nn.NLLLoss() # Only train the classifier parameters, feature parameters are frozen optimizer = optim.Adam(model.classifier.parameters(), lr=learn_rate) model.to(device) # Move model to either CPU or GPU train_losses, valid_losses, test_losses = [], [], [] epochs = in_arg.epochs with active_session(): for e in range(epochs): running_loss = 0 # ----------- Training Pass ----------- for images, labels in train_loader: # Move image and label tensors to default device images, labels = images.to(device), labels.to(device) optimizer.zero_grad() # Zero gradient log_pbs = model.forward(images) # Forward pass loss = criterion(log_pbs, labels) # Calulate the loss loss.backward() # Calculate gradients with loss optimizer.step() # Update weights running_loss += loss.item() # ---------- Validation Pass ---------- else: valid_loss = 0 accuracy = 0 with torch.no_grad(): model.eval() # Eval mode - dropout off for images, labels in valid_loader: # Move image and label tensors to default device images, labels = images.to(device), labels.to(device) valid_log_pbs = model.forward(images) # Forward pass valid_loss += criterion(valid_log_pbs, labels) # Calculate validation loss pbs = torch.exp(valid_log_pbs) # Calculate validation probabilities top_p, top_c = pbs.topk(1, dim=1) # Get top predicted class from our model equality = top_c == labels.view(*top_c.shape) # Check if top class == label accuracy += torch.mean(equality.type(torch.FloatTensor)) # Calculate accuracy model.train() # Train mode train_losses.append(running_loss/len(train_loader)) valid_losses.append(valid_loss/len(valid_loader)) # --- Print Statements --- print("Epochs: {}/{} -- ".format(e+1, epochs), "Training Loss: {:.3f} -- ".format(running_loss/len(train_loader)), "Valid Loss: {:.3f} -- ".format(valid_loss/len(valid_loader)), "Valid Accuracy: {:.3f}% -- ".format(accuracy.item()/len(valid_loader)*100)) ## ------------- # Run model on test images to get accuracy on new images test_loss = 0 test_accuracy = 0 with torch.no_grad(): model.eval() for images, labels in test_loader: images, labels = images.to(device), labels.to(device) # Transfer Tensors to default device test_log_pbs = model.forward(images) # Forward pass test_loss += criterion(test_log_pbs, labels) # Calculate loss ps = torch.exp(test_log_pbs) top_p, top_c = ps.topk(1, dim=1) equality = top_c == labels.view(*top_c.shape) test_accuracy += torch.mean(equality.type(torch.FloatTensor)) model.train() # Train mode test_losses.append(test_loss/len(test_loader)) # --- Print Statements --- print("Test Loss: {:.3f} -- ".format(test_loss/len(test_loader)), "Test Accuracy: {:.3f}% -- ".format(test_accuracy.item()/len(test_loader)*100)) ## ------------- # Save the model checkpoint model_functions.save_checkpoint(train_data, epochs, model, in_arg.save_dir)
def main(): # Measures total program runtime by collecting start time start_time = time() # Collect training parameter from the console interface in_arg = get_input_train() # Check consistency of the input parameters control_input_args_train(in_arg.data_dir, in_arg.save_dir, in_arg.arch, in_arg.hidden_units, in_arg.gpu) # Choose betwen GPU and CPU if in_arg.gpu[:1].lower() == 'y': device = 'cuda:0' else: device = 'cpu' print(f"\n Running on '{device}' device...\n") # Load training and validation dataloaders purpose = 'train' train_dataloader = create_dataloader(in_arg.data_dir, purpose) purpose = 'valid' valid_dataloader = create_dataloader(in_arg.data_dir, purpose) #Build and train the classifier network model = train_network(device, train_dataloader, valid_dataloader, in_arg.arch, int(in_arg.hidden_units), int(in_arg.epochs), float(in_arg.learning_rate), float(in_arg.dropout_rate)) #Test accuracy of the classifier netwoork build purpose = 'test' batch_size = 5 test_dataloader = create_dataloader(in_arg.data_dir, purpose, batch_size) result = evaluate_network(model, test_dataloader) #Saved the built classifier network if accuracy is higher than 40% if result > 40: dataset = datasets.ImageFolder(in_arg.data_dir + '/train') # Attach category attribute to the model to facilitate classe inference during prediction model.class_to_idx = dataset.class_to_idx saved_model = save_checkpoint(model, in_arg.save_dir, in_arg.arch, result) print(f" GOOD PERFORMANCE!!!" f" The trained model was saved...{saved_model}" f" Test accuracy: {result:.3f} %") else: print(f" BAD PERFORMANCE!!!" f" The trained model was not saved..." f" Test accuracy: {result:.3f} %") # Measure total program runtime by collecting end time end_time = time() # Computes overall runtime in seconds & prints it in hh:mm:ss format tot_time = end_time - start_time print( "\n** Total Elapsed Runtime:", str(int((tot_time / 3600))) + ":" + str(int( (tot_time % 3600) / 60)) + ":" + str(int((tot_time % 3600) % 60)))