def predict(imagePath, modelPath=None): # load trained model if (modelPath == None): predict_model = model else: checkpoint = torch.load(modelPath, map_location=lambda storage, loc: storage) predict_model = Net().double() if args.cuda: predict_model = predict_model.cuda() predict_model.load_state_dict(checkpoint['state_dict']) # load image image = io.imread(imagePath) transform = transforms.Compose([CropSquare(), Rescale(256), ToTensor()]) image = transform(image) data = image.unsqueeze(0) data = Variable(data) output = predict_model(data) # get the index of the max log-probability pred = output.data.max(1, keepdim=True)[1] print(pred.item()) return pred.item()
def run(): print("CUDA is available: {}".format(torch.cuda.is_available())) data_transform = transforms.Compose( [Rescale(250), CenterCrop(224), Normalize(), ToTensor()]) # loader will split datatests into batches witht size defined by batch_size train_loader = initialize_train_loader(data_transform) test_loader = initialize_test_loader(data_transform) model_id = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime()) # instantiate the neural network net = Net() net.to(device=device) summary(net, (1, 224, 224)) # define the loss function using SmoothL1Loss criterion = nn.SmoothL1Loss() # define the params updating function using Adam optimizer = optim.Adam(net.parameters(), lr=0.001) loss_logger = [] for i in range(1, epochs + 1): model_name = 'model-{}-epoch-{}.pt'.format(model_id, i) # train all data for one epoch train(net, criterion, optimizer, i, train_loader, model_id, loss_logger) # evaludate the accuracy after each epoch evaluate(net, criterion, i, test_loader) # save model after every 5 epochs # https://discuss.pytorch.org/t/loading-a-saved-model-for-continue-training/17244/3 # https://github.com/pytorch/pytorch/issues/2830 # https://pytorch.org/tutorials/beginner/saving_loading_models.html if i % 5 == 1: torch.save( { 'epoch': i, 'model': net.state_dict(), 'optimizer': optimizer.state_dict(), 'loss_logger': loss_logger, }, model_dir + model_name) print("Finished training!") model_name = 'model-{}-final.pt'.format(model_id) torch.save( { 'epoch': epochs, 'model': net.state_dict(), 'optimizer': optimizer.state_dict(), 'loss_logger': loss_logger, }, model_dir + model_name)
def main(): hyp_batch_size = 20 net = Net2() model_dir = '../saved_models/' model_name = 'keypoints_model_2.pt' data_transform = transforms.Compose([ Rescale(256), RandomCrop(224), Normalize(), ToTensor() ]) # retreive the saved model net_state_dict = torch.load(model_dir+model_name) net.load_state_dict(net_state_dict) # load the test data test_dataset = FacialKeypointsDataset(csv_file='../files/test_frames_keypoints.csv', root_dir='../files/test/', transform=data_transform) # load test data in batches batch_size = hyp_batch_size test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True, num_workers=0) test_images, test_outputs, gt_pts = net_sample_output(test_loader, net) print(test_images.data.size()) print(test_outputs.data.size()) print(gt_pts.size()) # Get the weights in the first conv layer, "conv1" # if necessary, change this to reflect the name of your first conv layer weights1 = net.conv1.weight.data w = weights1.numpy() filter_index = 0 print(w[filter_index][0]) print(w[filter_index][0].shape) # display the filter weights plt.imshow(w[filter_index][0], cmap='gray') #plt.show() ##TODO: load in and display any image from the transformed test dataset i = 1 show_image(test_images, w, i)
def __init__(self, root_dir=None): self.data_root_dir = root_dir or './data/' self.training_csv = os.path.join(self.data_root_dir, 'training_frames_keypoints.csv') self.training_data_dir = os.path.join(self.data_root_dir, 'training/') self.test_csv = os.path.join(self.data_root_dir, 'test_frames_keypoints.csv') self.test_data_dir = os.path.join(self.data_root_dir, 'test/') self.key_pts_frame = pd.read_csv(self.training_csv) self.face_dataset = FacialKeypointsDataset( csv_file=self.training_csv, root_dir=self.training_data_dir) self.face_dataset_len = len(self.face_dataset) # define the data tranform # order matters! i.e. rescaling should come before a smaller crop self.data_transform = transforms.Compose( [Rescale(250), RandomCrop(224), Normalize(), ToTensor()]) self.transformed_training_data = self.transform_data( self.training_csv, self.training_data_dir) self.transformed_test_data = self.transform_data( self.test_csv, self.test_data_dir)
def data_transform(npy_train, npy_test, batch_size=64, shuffle=True): # Setting up our image transforms DATA_TRANSFORM = transforms.Compose( [Rescale(256), RandomCrop(224), Normalize(), ToTensor()]) # importing in the Custome dataset TRANSFORMED_DATASET_TRAIN = KeypointDataSet(npy_file=npy_train, root_dir='data/', transform=DATA_TRANSFORM) TRANSFORMED_DATASET_TEST = KeypointDataSet(npy_file=npy_test, root_dir='data/', transform=DATA_TRANSFORM) # passing in the trainformed data into the dataLoader TRAIN_LOADER = DataLoader(TRANSFORMED_DATASET_TRAIN, batch_size=64, shuffle=True, pin_memory=True) TEST_LOADER = DataLoader(TRANSFORMED_DATASET_TEST, batch_size=64, shuffle=True, pin_memory=True) return TRAIN_LOADER, TEST_LOADER
from train import train_net if __name__ == "__main__": torch.cuda.empty_cache() offline = True device = torch.device("cuda" if torch.cuda.is_available() else "cpu") n_epochs = 20 print("AI Running on", device) net = FCN().apply(initialize_weights_advance_).to(device) print(net) data_transform = transforms.Compose( [Rescale(250), RandomCrop(224), Normalize(), ToTensor()]) transformed_dataset = FacialKeypointsDataset( csv_file='data/training_frames_keypoints.csv', root_dir='data/training/', transform=data_transform) # load training data in batches batch_size = 128 train_loader = DataLoader(transformed_dataset, batch_size=batch_size, shuffle=True, num_workers=4) criterion = nn.MSELoss()
n = 30 if args['model'] == "NaimishNet": net = NaimishNet(n) elif args['model'] == "VggFace": net = VggFace(n) elif args['model'] == "Custom": net = Net2(n) else: net = LeNet5(n) model_name = args['model'] print(net) device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') # order matters! i.e. rescaling should come before a smaller crop train_transform = transforms.Compose([Rescale(110),RandomCrop(96),Albu(),Normalize(args["dataset"]),ToTensor()]) test_transform = transforms.Compose([Normalize(args["dataset"]),ToTensor()]) # testing that you've defined a transform assert(train_transform is not None and test_transform is not None), 'Define a data_transform' # create the transformed dataset if args["dataset"] == "Kaggle": X, y = load_KagggleDataset(split=args['split'],train_30=args['train30'],train_8=args['train8']) X_test, y_test = X[:300], y[:300] X_train, y_train = X[300:], y[300:] transformed_dataset = KagggleDataset(X_train, y_train, train_transform) test_dataset = KagggleDataset(X_test, y_test, test_transform) sub, div = 48., 48. else:
args.cuda = not args.no_cuda and torch.cuda.is_available() torch.manual_seed(args.seed) if args.cuda: torch.cuda.manual_seed(args.seed) ###################################################################### # Data # ==================== from data_load import ChicagoFaceDatabase, InstagramDatabase, ToTensor, Rescale, CropSquare CFD_train_dataset = ChicagoFaceDatabase( root_dir='../data/ChicagoFaceDatabase/', transform=transforms.Compose([CropSquare(), Rescale(256), ToTensor()]), train=True) CFD_train_loader = torch.utils.data.DataLoader(dataset=CFD_train_dataset, batch_size=args.batch_size, shuffle=True) CFD_test_dataset = ChicagoFaceDatabase( root_dir='../data/ChicagoFaceDatabase/', transform=transforms.Compose([CropSquare(), Rescale(256), ToTensor()]), train=False) CFD_test_loader = torch.utils.data.DataLoader(dataset=CFD_test_dataset, batch_size=args.batch_size, shuffle=True)
opti = getattr(optim, args.optimizer) optimizer = opti(model.parameters(), lr=args.lr) assert args.loss_func in loss_funcs, f"Error: Network architecture {args.loss_func} not found." criterion = loss_funcs[args.loss_func] # hard-coded scheduler = optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1) # Define a transform data_transform = transforms.Compose([ Rescale((224,224)), #RandomCrop(), Normalize(), ToTensor(), ]) # create the transformed dataset train_val_dataset = FacialKeypointsDataset(csv_file='data/training_frames_keypoints.csv', root_dir='data/training/', transform=data_transform) # for faster experimentation select only a subset of images if args.subset_size > 0: train_val_dataset = Subset(train_val_dataset, range(args.subset_size)) print('Number of images: ', len(train_val_dataset)) # split train/val - hard coded train_size = 0.8
from data_load import FacialKeypointsDataset, Rescale, RandomCrop, Normalize, ToTensor from models import Net net = Net() print(net) criterion = nn.SmoothL1Loss() optimizer = optim.Adam(net.parameters(), lr=0.01) """ Load data """ # define the data transform data_transform = transforms.Compose([Rescale(250), RandomCrop(224), Normalize(), ToTensor()]) # create the transformed dataset transformed_dataset = FacialKeypointsDataset(csv_file='data/training_frames_keypoints.csv', root_dir='data/training/', transform=data_transform) # load training data in batches batch_size = 50 train_loader = DataLoader(transformed_dataset, batch_size=batch_size, shuffle=True, num_workers=0) def train_net(n_epochs):
# * Convolutional layers # * Maxpooling layers # * Fully-connected layers # # # In[134]: # import the usual resources ## TODO: define the data_transform using transforms.Compose([all tx's, . , .]) # order matters! i.e. rescaling should come before a smaller crop # testing that you've defined a transform data_transform = transforms.Compose([ Rescale(224), # RandomCrop(224), Normalize(), ToTensor() ]) assert (data_transform is not None), 'Define a data_transform' # In[ ]: # In[136]: # In[137]: ###########load the csv # order matters! i.e. rescaling should come before a smaller crop data_transform = transforms.Compose([ Rescale(224), # RandomCrop(222), Normalize(), ToTensor() ]) # create the transformed dataset
if is_debug: print('fc1.out_shape:', x.shape) # a modified x, having gone through all the layers of your model, should be returned return x if __name__ == '__main__': import os os.chdir('/Users/rawk/Projects/Project Zero/MLND-projects/cv-project0-facial-keypoints/') from data_load import FacialKeypointsDataset from data_load import Rescale, RandomCrop, Normalize, ToTensor from torch.utils.data import Dataset, DataLoader from torchvision import transforms, utils data_transform = transforms.Compose([Rescale((250, 250)), RandomCrop((224, 224)), Normalize(), ToTensor()]) transformed_dataset = FacialKeypointsDataset(csv_file='./data/training_frames_keypoints.csv', root_dir='./data/training/', transform=data_transform) batch_size = 2 data_loader = DataLoader(transformed_dataset, batch_size=batch_size, shuffle=True, num_workers=4) for i, sample in enumerate(data_loader): images = sample['image'] images = images.type(torch.FloatTensor) net = Net()
def main(): #------------------------------------------------------------------------------------------------------------------ # Hyperparameters hyp_epochs = 5 hyp_batch_size = 20 #hyp_optim = "SGD" hyp_optim = "Adam" #hyp_net = Net1() hyp_net = Net2() print("Hyperparameters") print("--------------") print("Epochs = ", hyp_epochs) print("Batch Size = ", hyp_batch_size) print("Optimizer = ", hyp_optim) print("--------------") ## TODO: Define the Net in models.py net = hyp_net print(net) ## TODO: define the data_transform using transforms.Compose([all tx's, . , .]) # order matters! i.e. rescaling should come before a smaller crop data_transform = transforms.Compose( [Rescale(256), RandomCrop(224), Normalize(), ToTensor()]) # testing that you've defined a transform assert (data_transform is not None), 'Define a data_transform' # create the transformed dataset transformed_dataset = FacialKeypointsDataset( csv_file='../files/training_frames_keypoints.csv', root_dir='../files/training/', transform=data_transform) print('Number of images: ', len(transformed_dataset)) # iterate through the transformed dataset and print some stats about the first few samples for i in range(4): sample = transformed_dataset[i] print(i, sample['image'].size(), sample['keypoints'].size()) # load training data in batches batch_size = hyp_batch_size train_loader = DataLoader(transformed_dataset, batch_size=batch_size, shuffle=True, num_workers=0) # load in the test data, using the dataset class # AND apply the data_transform you defined above # create the test dataset test_dataset = FacialKeypointsDataset( csv_file='../files/test_frames_keypoints.csv', root_dir='../files/test/', transform=data_transform) # load test data in batches batch_size = hyp_batch_size test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=True, num_workers=0) # test the model on a batch of test images # call the above function # returns: test images, test predicted keypoints, test ground truth keypoints test_images, test_outputs, gt_pts = net_sample_output(test_loader, net) # print out the dimensions of the data to see if they make sense print(test_images.data.size()) print(test_outputs.data.size()) print(gt_pts.size()) # visualize the output # by default this shows a batch of 10 images # call it _visualise = False if _visualise == True: visualize_output(test_images, test_outputs, gt_pts) ## TODO: Define the loss and optimization import torch.optim as optim criterion = nn.MSELoss() hyp_optimizer = None if hyp_optim == "Adam": hyp_optimizer = optim.Adam(net.parameters(), lr=0.001) if hyp_optim == "SGD": hyp_optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9) optimizer = hyp_optimizer # train your network n_epochs = hyp_epochs # start small, and increase when you've decided on your model structure and hyperparams # this is a Workspaces-specific context manager to keep the connection # alive while training your model, not part of pytorch train_net(n_epochs, train_loader, net, criterion, optimizer) # get a sample of test data again test_images, test_outputs, gt_pts = net_sample_output(test_loader, net) print(test_images.data.size()) print(test_outputs.data.size()) print(gt_pts.size()) ## TODO: change the name to something uniqe for each new model model_dir = '../saved_models/' model_name = 'keypoints_model_2.pt' # after training, save your model parameters in the dir 'saved_models' torch.save(net.state_dict(), model_dir + model_name) # -------------------------------------------------------------------- # To run the following code after retreiving an existing model, # you can do so in the resume.py file # -------------------------------------------------------------------- # Get the weights in the first conv layer, "conv1" # if necessary, change this to reflect the name of your first conv layer weights1 = net.conv1.weight.data w = weights1.numpy() filter_index = 0 print(w[filter_index][0]) print(w[filter_index][0].shape) # display the filter weights plt.imshow(w[filter_index][0], cmap='gray') ##TODO: load in and display any image from the transformed test dataset i = 1 show_image(test_images, w, i)
def train(epochs, lr=1e-3, batch_size=32, seed=23, kernel_width=5, kernel_fwhm=3, verbose=True, save=True, load_model=False, model_path=None): if load_model: model.load_state_dict(torch.load(model_path)) torch.cuda.manual_seed_all(seed) trsfm = transforms.Compose([Rescale(8), PlotLabels(100), ToTensor()]) train = ReadDataset(csv_file=home + "/data/dataset_cae/train_label.csv", tif_file=home + "/data/dataset_cae/train_data.tif", transform=trsfm) val = ReadDataset(csv_file=home + "/data/dataset_cae/val_label.csv", tif_file=home + "/data/dataset_cae/val_data.tif", transform=trsfm) train_loader = torch.utils.data.DataLoader(train, batch_size=batch_size, shuffle=True) val_loader = torch.utils.data.DataLoader(val, batch_size=batch_size, shuffle=True) val_iter = iter(val_loader) # function to save and close def saveit(): if save: os.makedirs(home + "/data/temp/{}".format(timestamp)) file_path = home + '/data/temp/{}/cae_model_{}.pt'.format( timestamp, timestamp) torch.save(model.state_dict(), file_path) print(' -------------------------------') print("model saved:", file_path) else: print(' -------------------------------') # make a gaussian kernel def Gauss(size, fwhm=3, center=None): """ Make a square gaussian kernel. size is the length of a side of the square fwhm is full-width-half-maximum, which can be thought of as an effective radius. """ x = np.arange(0, size, 1, float) y = x[:, np.newaxis] if center is None: x0 = y0 = size // 2 else: x0 = center[0] y0 = center[1] return np.exp(-4 * np.log(2) * ((x - x0)**2 + (y - y0)**2) / fwhm**2) # Gaussian kernel kernel = Variable( torch.FloatTensor( Gauss(kernel_width, kernel_fwhm).reshape(1, 1, kernel_width, kernel_width)).cuda()) # define the optimizer criterion = nn.MSELoss() optimizer = optim.Adam(model.parameters(), lr=lr, weight_decay=1e-5) print(' epochs: ', epochs, ' batch_size: ', batch_size, ' lr: ', lr, 'seed: ', torch.cuda.initial_seed()) print('Training... ') print(' | epoch| train_loss| n_batch|') # Training the ConvNet auto-encoder try: for epoch in range(epochs): # loop over the dataset multiple times t = tqdm(train_loader, ncols=80, leave=True, bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt}') running_loss = [] for i, data in enumerate(t): # =======inputs/labels======= inputs, labels = data['image'], data['positions'] inputs, labels = Variable(inputs).cuda(), Variable( labels).cuda() # ==========forward========== outputs = model(inputs) loss = criterion(F.conv2d(outputs, kernel, padding=2), F.conv2d(labels, kernel, padding=2)) # ==========backward========== optimizer.zero_grad() loss.backward() optimizer.step() # ============================ running_loss.append(loss.data[0]) # tqdm update t.set_description(' |{:5.0f} |{:12.6f}|{:8.0f}|'.format( epoch + 1, np.mean(running_loss), i + 1)) t.refresh() # write to visdom if verbose: if epoch == 0: vis = visdom.Visdom() label_win = vis.images(utils.make_grid( labels.cpu().data[:4], padding=5, pad_value=1, normalize=True, scale_each=True), opts=dict(title='label images')) pred_win = vis.images(utils.make_grid( outputs.cpu().data[:4], padding=5, pad_value=1, normalize=True, scale_each=True), opts=dict(title='prediction images')) loss_win = vis.line( X=np.array([epoch + 1]), Y=np.array([np.mean(running_loss)]), opts=dict( width=850, xlabel='<b>epochs</b>', ylabel='training loss', markersize=5, markers=True, title="<b> Conv_Autoencoder </b> training loss")) else: vis.images(utils.make_grid(labels.cpu().data[:4], padding=5, pad_value=1, normalize=True, scale_each=True), win=label_win, opts=dict(title='label images')) vis.images(utils.make_grid(outputs.cpu().data[:4], padding=5, pad_value=1, normalize=True, scale_each=True), win=pred_win, opts=dict(title='prediction images')) vis.line( X=np.array([epoch + 1]), Y=np.array([np.mean(running_loss)]), win=loss_win, update='append', opts=dict( width=850, xlabel='<b>epochs</b>', ylabel='training loss', markersize=5, markers=True, title="<b> Conv_Autoencoder </b> training loss")) saveit() except KeyboardInterrupt: saveit()
def run_epochs(config, checkpoint_path): print("CUDA is available: {}".format(torch.cuda.is_available())) # Define data loader: data preprocessing and augmentation # I use same procedures for all models that consumes imagenet-2012 dataset for simplicity imagenet_train_transform = transforms.Compose([ Rescale(256), RandomHorizontalFlip(0.5), RandomCrop(224), ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0), ToTensor(), # https://github.com/pytorch/examples/blob/master/imagenet/main.py#L195 # this is pre-calculated mean and std of imagenet dataset Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) imagenet_val_transform = transforms.Compose([ Rescale(256), CenterCrop(224), ToTensor(), Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) train_loader = initialize_train_loader(imagenet_train_transform, config) val_loader = initialize_val_loader(imagenet_val_transform, config) # Define the neural network. Model = config.get('model') model_params = config.get('model_params') if model_params is not None: net = Model(**model_params) else: net = Model() # transfer variables to GPU if present net.to(device=device) # Print the network structure given 3x32x32 input # need to put this before DataParallel to avoid "Expected more than 1 value per channel when training" error # https://github.com/pytorch/pytorch/issues/4534 summary(net, (3, 224, 224)) # Wrap it with DataParallel to train with multiple GPUs if torch.cuda.device_count() > 1: print("Using", torch.cuda.device_count(), "GPUs!") net = nn.DataParallel(net) # Define the loss function. CrossEntrophyLoss is the most common one for classification task. criterion = nn.CrossEntropyLoss() # Define the optimizer Optim = config.get('optimizer') optimizer = Optim( net.parameters(), **config.get('optimizer_params'), ) # Define the scheduler Sched = config.get('scheduler') scheduler = Sched( optimizer, **config.get('scheduler_params'), ) loggers = initialize_loggers() model_id = time.strftime("%Y-%m-%dT%H:%M:%S", time.localtime()) model_name = config.get('name') start_epoch = 1 if checkpoint_path is not None: net, optimizer, scheduler, loggers, start_epoch = load_checkpoint( checkpoint_path, net, optimizer, scheduler, loggers, ) validate(val_loader, net, criterion, 0, loggers) for epoch in range(start_epoch, config.get('total_epochs') + 1): train( train_loader, net, criterion, optimizer, epoch, loggers, ) val_loss, top1_acc, top5_acc = validate( val_loader, net, criterion, epoch, loggers, ) # for ReduceLROnPlateau scheduler, we need to use top1_acc as metric if isinstance(scheduler, optim.lr_scheduler.ReduceLROnPlateau): scheduler.step(top1_acc) else: scheduler.step() checkpoint_file = '{}-{}-epoch-{}.pt'.format( model_name, model_id, epoch, ) torch.save( { 'epoch': epoch, 'model': net.state_dict(), 'optimizer': optimizer.state_dict(), 'scheduler': scheduler.state_dict(), 'loggers': loggers, }, model_dir + checkpoint_file)
def plot_face_pts(img, pts): plt.imshow(img[:, :, 0], cmap='gray') for i in range(1, 31, 2): plt.plot(pts[i - 1], pts[i], 'b.') #load models net_8 = Net2(8) net_8.load_state_dict( torch.load('./saved_models/Kaggle_Custom_1.68410162627697.pt')) net_30 = Net2(30) net_30.load_state_dict( torch.load('./saved_models/Kaggle_Custom_1.6080801971256733.pt')) device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu') data_transform = transforms.Compose([Normalize("Kaggle"), ToTensor()]) # testing that you've defined a transform assert (data_transform is not None), 'Define a data_transform' X, y = load_KagggleDataset(test=True) y = np.zeros((X.shape[0], 30)) test_dataset = KagggleDataset(X, y, data_transform) batch_size = 32 test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False, num_workers=0)