def main_run(numEpochs, lr, stepSize, decayRate, trainBatchSize, seqLen, evalInterval, evalMode, numWorkers, outDir, modelUsed, pretrained, train_test_split, directory, crossValidation, folds): compDataset, classCount, class_names = make_split(directory) if crossValidation: data, label = compDataset kFoldCrossValid(folds, data, label, numEpochs, evalMode, numWorkers, lr, stepSize, decayRate, trainBatchSize, seqLen) else: (trainDataset, trainLabels), (validationDataset, validationLabels), (testDataset, testLabels) = sampleFromClass( compDataset, classCount, train_test_split) model, accuracy = modelTrain(modelUsed, pretrained, trainDataset, trainLabels, validationDataset, validationLabels, numEpochs, evalInterval, evalMode, outDir, numWorkers, lr, stepSize, decayRate, trainBatchSize, seqLen, True) '''for printing confusion matrix''' mean = [0.485, 0.456, 0.406] std = [0.229, 0.224, 0.225] normalize = Normalize(mean=mean, std=std) if evalMode == 'centerCrop': test_spatial_transform = Compose( [Scale(256), CenterCrop(224), ToTensor(), normalize]) elif evalMode == 'tenCrops': test_spatial_transform = Compose( [Scale(256), TenCrops(size=224, mean=mean, std=std)]) elif evalMode == 'fiveCrops': test_spatial_transform = Compose( [Scale(256), FiveCrops(size=224, mean=mean, std=std)]) elif evalMode == 'horFlip': test_spatial_transform = Compose([ Scale(256), CenterCrop(224), FlippedImagesTest(mean=mean, std=std) ]) vidSeqTest = makeDataset(testDataset, testLabels, seqLen=seqLen, spatial_transform=test_spatial_transform) testLoader = torch.utils.data.DataLoader(vidSeqTest, batch_size=1, shuffle=False, num_workers=int(numWorkers / 2), pin_memory=True) numTestInstances = vidSeqTest.__len__() print('Number of test samples = {}'.format(numTestInstances)) modelFolder = './experiments_' + outDir + '_' + modelUsed + '_' + str( pretrained) # Dir for saving models and log files savePathClassifier = (modelFolder + '/bestModel.pth') torch.save(model.state_dict(), savePathClassifier) '''running test samples and printing confusion matrix''' model.train(False) print('Testing...') LossEpoch = 0 testIter = 0 pred = None targ = None numCorrTest = 0 for j, (inputs, targets) in enumerate(testLoader): testIter += 1 #if evalMode == 'centerCrop': if (torch.cuda.is_available()): inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4).cuda(), requires_grad=False) labelVariable = Variable(targets.cuda(async=True), requires_grad=False) else: inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4), requires_grad=False) labelVariable = Variable(targets, requires_grad=False) # else: # if(torch.cuda.is_available()): # inputVariable1 = Variable(inputs[0].permute(1, 0, 2, 3, 4).cuda(), requires_grad=False) # labelVariable = Variable(targets.cuda(async=True), requires_grad=False) # else: # inputVariable1 = Variable(inputs[0].permute(1, 0, 2, 3, 4), requires_grad=False) # labelVariable = Variable(targets, requires_grad=False) outputLabel = model(inputVariable1) outputProb = torch.nn.Softmax(dim=1)(outputLabel) _, predicted = torch.max(outputProb.data, 1) if pred is None: pred = predicted.cpu().numpy() targ = targets[0].cpu().numpy() else: pred = np.append(pred, predicted.cpu().numpy()) targ = np.append(targ, targets[0].cpu().numpy()) # if(torch.cuda.is_available()): # numCorrTest += (predicted == targets[0].cuda()).sum() # else: # numCorrTest += (predicted == targets[0]).sum() # Compute confusion matrix cnf_matrix = confusion_matrix(targ, pred) np.set_printoptions(precision=2) # Plot non-normalized confusion matrix plt.figure() plot_confusion_matrix(cnf_matrix, classes=class_names, title='Confusion matrix, without normalization') plt.savefig(modelFolder + "/no_norm_confusion_matrix.png") # Plot normalized confusion matrix plt.figure() plot_confusion_matrix(cnf_matrix, classes=class_names, normalize=True, title='Normalized confusion matrix') plt.savefig(modelFolder + "/confusion_matrix.png") return True
def main_run(numEpochs, lr, stepSize, decayRate, trainBatchSize, seqLen, memSize, evalInterval, evalMode, numWorkers, outDir, fightsDir_train, noFightsDir_train, fightsDir_test, noFightsDir_test): train_dataset_dir_fights = fightsDir_train train_dataset_dir_noFights = noFightsDir_train test_dataset_dir_fights = fightsDir_test test_dataset_dir_noFights = noFightsDir_test trainDataset, trainLabels, trainNumFrames = make_split( train_dataset_dir_fights, train_dataset_dir_noFights) testDataset, testLabels, testNumFrames = make_split( test_dataset_dir_fights, test_dataset_dir_noFights) mean = [0.485, 0.456, 0.406] std = [0.229, 0.224, 0.225] normalize = Normalize(mean=mean, std=std) spatial_transform = Compose([ Scale(256), RandomHorizontalFlip(), MultiScaleCornerCrop([1, 0.875, 0.75, 0.65625], 224), ToTensor(), normalize ]) vidSeqTrain = VideoDataset(trainDataset, trainLabels, trainNumFrames, spatial_transform=spatial_transform, seqLen=seqLen) trainLoader = torch.utils.data.DataLoader(vidSeqTrain, batch_size=trainBatchSize, shuffle=True, num_workers=numWorkers, pin_memory=True, drop_last=True) if evalMode == 'centerCrop': test_spatial_transform = Compose( [Scale(256), CenterCrop(224), ToTensor(), normalize]) testBatchSize = 1 elif evalMode == 'tenCrops': test_spatial_transform = Compose( [Scale(256), TenCrops(size=224, mean=mean, std=std)]) testBatchSize = 1 elif evalMode == 'fiveCrops': test_spatial_transform = Compose( [Scale(256), FiveCrops(size=224, mean=mean, std=std)]) testBatchSize = 1 elif evalMode == 'horFlip': test_spatial_transform = Compose([ Scale(256), CenterCrop(224), FlippedImagesTest(mean=mean, std=std) ]) testBatchSize = 1 vidSeqTest = VideoDataset(testDataset, testLabels, testNumFrames, seqLen=seqLen, spatial_transform=test_spatial_transform) testLoader = torch.utils.data.DataLoader(vidSeqTest, batch_size=testBatchSize, shuffle=False, num_workers=int(numWorkers / 2), pin_memory=True) numTrainInstances = vidSeqTrain.__len__() numTestInstances = vidSeqTest.__len__() print('Number of training samples = {}'.format(numTrainInstances)) print('Number of testing samples = {}'.format(numTestInstances)) modelFolder = './experiments_' + outDir # Dir for saving models and log files # Create the dir if os.path.exists(modelFolder): print(modelFolder + ' exists!!!') sys.exit() else: os.makedirs(modelFolder) # Log files writer = SummaryWriter(modelFolder) trainLogLoss = open((modelFolder + '/trainLogLoss.txt'), 'w') trainLogAcc = open((modelFolder + '/trainLogAcc.txt'), 'w') testLogLoss = open((modelFolder + '/testLogLoss.txt'), 'w') testLogAcc = open((modelFolder + '/testLogAcc.txt'), 'w') model = ViolenceModel(mem_size=memSize) trainParams = [] for params in model.parameters(): params.requires_grad = True trainParams += [params] model.train(True) model.cuda() lossFn = nn.CrossEntropyLoss() optimizerFn = torch.optim.RMSprop(trainParams, lr=lr) optimScheduler = torch.optim.lr_scheduler.StepLR(optimizerFn, stepSize, decayRate) minAccuracy = 50 for epoch in range(numEpochs): optimScheduler.step() epochLoss = 0 numCorrTrain = 0 iterPerEpoch = 0 model.train(True) print('Epoch = {}'.format(epoch + 1)) writer.add_scalar('lr', optimizerFn.param_groups[0]['lr'], epoch + 1) for i, (inputs, targets) in enumerate(trainLoader): iterPerEpoch += 1 optimizerFn.zero_grad() inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4).cuda()) labelVariable = Variable(targets.cuda()) outputLabel = model(inputVariable1) loss = lossFn(outputLabel, labelVariable) loss.backward() optimizerFn.step() outputProb = torch.nn.Softmax(dim=1)(outputLabel) _, predicted = torch.max(outputProb.data, 1) numCorrTrain += (predicted == targets.cuda()).sum() epochLoss += loss.data[0] avgLoss = epochLoss / iterPerEpoch trainAccuracy = (numCorrTrain / numTrainInstances) * 100 print('Training: Loss = {} | Accuracy = {}% '.format( avgLoss, trainAccuracy)) writer.add_scalar('train/epochLoss', avgLoss, epoch + 1) writer.add_scalar('train/accuracy', trainAccuracy, epoch + 1) trainLogLoss.write('Training loss after {} epoch = {}\n'.format( epoch + 1, avgLoss)) trainLogAcc.write('Training accuracy after {} epoch = {}\n'.format( epoch + 1, trainAccuracy)) if (epoch + 1) % evalInterval == 0: model.train(False) print('Evaluating...') testLossEpoch = 0 testIter = 0 numCorrTest = 0 for j, (inputs, targets) in enumerate(testLoader): testIter += 1 if evalMode == 'centerCrop': inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4).cuda(), volatile=True) else: inputVariable1 = Variable(inputs[0].cuda(), volatile=True) labelVariable = Variable(targets.cuda(async=True), volatile=True) outputLabel = model(inputVariable1) outputLabel_mean = torch.mean(outputLabel, 0, True) testLoss = lossFn(outputLabel_mean, labelVariable) testLossEpoch += testLoss.data[0] _, predicted = torch.max(outputLabel_mean.data, 1) numCorrTest += (predicted == targets[0]).sum() testAccuracy = (numCorrTest / numTestInstances) * 100 avgTestLoss = testLossEpoch / testIter print('Testing: Loss = {} | Accuracy = {}% '.format( avgTestLoss, testAccuracy)) writer.add_scalar('test/epochloss', avgTestLoss, epoch + 1) writer.add_scalar('test/accuracy', testAccuracy, epoch + 1) testLogLoss.write('Test Loss after {} epochs = {}\n'.format( epoch + 1, avgTestLoss)) testLogAcc.write('Test Accuracy after {} epochs = {}%\n'.format( epoch + 1, testAccuracy)) if testAccuracy > minAccuracy: savePathClassifier = (modelFolder + '/bestModel.pth') torch.save(model, savePathClassifier) minAccuracy = testAccuracy trainLogAcc.close() testLogAcc.close() trainLogLoss.close() testLogLoss.close() writer.export_scalars_to_json(modelFolder + "/all_scalars.json") writer.close() return True
def modelTrain(modelUsed, pretrained, trainDataset, trainLabels, validationDataset, validationLabels, numEpochs, evalInterval, evalMode, outDir, numWorkers, lr, stepSize, decayRate, trainBatchSize, seqLen, plotting): mean = [0.485, 0.456, 0.406] std = [0.229, 0.224, 0.225] normalize = Normalize(mean=mean, std=std) spatial_transform = Compose([ Scale(256), RandomHorizontalFlip(), MultiScaleCornerCrop([1, 0.875, 0.75, 0.65625], 224), ToTensor(), normalize ]) vidSeqTrain = makeDataset(trainDataset, trainLabels, spatial_transform=spatial_transform, seqLen=seqLen) # torch iterator to give data in batches of specified size trainLoader = torch.utils.data.DataLoader(vidSeqTrain, batch_size=trainBatchSize, shuffle=True, num_workers=numWorkers, pin_memory=True, drop_last=True) if evalMode == 'centerCrop': test_spatial_transform = Compose( [Scale(256), CenterCrop(224), ToTensor(), normalize]) elif evalMode == 'tenCrops': test_spatial_transform = Compose( [Scale(256), TenCrops(size=224, mean=mean, std=std)]) elif evalMode == 'fiveCrops': test_spatial_transform = Compose( [Scale(256), FiveCrops(size=224, mean=mean, std=std)]) elif evalMode == 'horFlip': test_spatial_transform = Compose([ Scale(256), CenterCrop(224), FlippedImagesTest(mean=mean, std=std) ]) vidSeqValid = makeDataset(validationDataset, validationLabels, seqLen=seqLen, spatial_transform=test_spatial_transform) validationLoader = torch.utils.data.DataLoader(vidSeqValid, batch_size=1, shuffle=False, num_workers=int(numWorkers / 2), pin_memory=True) numTrainInstances = vidSeqTrain.__len__() numValidationInstances = vidSeqValid.__len__() print('Number of training samples = {}'.format(numTrainInstances)) print('Number of validation samples = {}'.format(numValidationInstances)) modelFolder = './experiments_' + outDir + '_' + modelUsed + '_' + str( pretrained) # Dir for saving models and log files # Create the dir if os.path.exists(modelFolder): pass else: os.makedirs(modelFolder) # Log files writer = SummaryWriter(modelFolder) trainLogLoss = open((modelFolder + '/trainLogLoss.txt'), 'a') trainLogAcc = open((modelFolder + '/trainLogAcc.txt'), 'a') validationLogLoss = open((modelFolder + '/validLogLoss.txt'), 'a') validationLogAcc = open((modelFolder + '/validLogAcc.txt'), 'a') model = ViolenceModel(modelUsed, pretrained) trainParams = [] for params in model.parameters(): if params.requires_grad: trainParams += [params] model.train(True) if (torch.cuda.is_available()): model.cuda() lossFn = nn.CrossEntropyLoss() optimizerFn = torch.optim.RMSprop(trainParams, lr=lr) optimizerFn.zero_grad() optimScheduler = torch.optim.lr_scheduler.StepLR(optimizerFn, stepSize, decayRate) minAccuracy = 50 train_loss = [] val_loss = [] train_acc = [] val_acc = [] bestmodel = None for epoch in range(numEpochs): optimScheduler.step() epochLoss = 0 numCorrTrain = 0 iterPerEpoch = 0 model.train(True) print('Epoch = {}'.format(epoch + 1)) writer.add_scalar('lr', optimizerFn.param_groups[0]['lr'], epoch + 1) for i, (inputs, targets) in enumerate(trainLoader): iterPerEpoch += 1 optimizerFn.zero_grad() if (torch.cuda.is_available()): inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4).cuda()) labelVariable = Variable(targets.cuda()) else: inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4)) labelVariable = Variable(targets) outputLabel = model(inputVariable1) loss = lossFn(outputLabel, labelVariable) loss.backward() optimizerFn.step() outputProb = torch.nn.Softmax(dim=1)(outputLabel) _, predicted = torch.max(outputProb.data, 1) if (torch.cuda.is_available()): numCorrTrain += (predicted == targets.cuda()).sum() else: numCorrTrain += (predicted == targets).sum() epochLoss += loss.item() avgLoss = epochLoss / iterPerEpoch trainAccuracy = (float(numCorrTrain) * 100) / float(numTrainInstances) train_loss.append(avgLoss) train_acc.append(trainAccuracy) print('Training: Loss = {} | Accuracy = {}% '.format( avgLoss, trainAccuracy)) writer.add_scalar('train/epochLoss', avgLoss, epoch + 1) writer.add_scalar('train/accuracy', trainAccuracy, epoch + 1) trainLogLoss.write('Training loss after {} epoch = {}\n'.format( epoch + 1, avgLoss)) trainLogAcc.write('Training accuracy after {} epoch = {}\n'.format( epoch + 1, trainAccuracy)) if (epoch + 1) % evalInterval == 0: model.train(False) print('Evaluating...') validationLossEpoch = 0 validationIter = 0 numCorrTest = 0 for j, (inputs, targets) in enumerate(validationLoader): validationIter += 1 #if evalMode == 'centerCrop': if (torch.cuda.is_available()): inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4).cuda(), requires_grad=False) labelVariable = Variable(targets.cuda(async=True), requires_grad=False) else: inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4), requires_grad=False) labelVariable = Variable(targets, requires_grad=False) # else: # if(torch.cuda.is_available()): # inputVariable1 = Variable(inputs[0].permute(1, 0, 2, 3, 4).cuda(), requires_grad=False) # labelVariable = Variable(targets.cuda(async=True), requires_grad=False) # else: # inputVariable1 = Variable(inputs[0].permute(1, 0, 2, 3, 4), requires_grad=False) # labelVariable = Variable(targets, requires_grad=False) outputLabel = model(inputVariable1) validationLoss = lossFn(outputLabel, labelVariable) validationLossEpoch += validationLoss.item() outputProb = torch.nn.Softmax(dim=1)(outputLabel) _, predicted = torch.max(outputProb.data, 1) if (torch.cuda.is_available()): numCorrTest += (predicted == targets[0].cuda()).sum() else: numCorrTest += (predicted == targets[0]).sum() validationAccuracy = (float(numCorrTest) * 100) / float(numValidationInstances) avgValidationLoss = validationLossEpoch / validationIter val_loss.append(avgValidationLoss) val_acc.append(validationAccuracy) print('Testing: Loss = {} | Accuracy = {}% '.format( avgValidationLoss, validationAccuracy)) writer.add_scalar('test/epochloss', avgValidationLoss, epoch + 1) writer.add_scalar('test/accuracy', validationAccuracy, epoch + 1) validationLogLoss.write('valid Loss after {} epochs = {}\n'.format( epoch + 1, avgValidationLoss)) validationLogAcc.write( 'valid Accuracy after {} epochs = {}%\n'.format( epoch + 1, validationAccuracy)) if validationAccuracy > minAccuracy: bestmodel = model minAccuracy = validationAccuracy '''plotting the accuracy and loss curves''' if plotting: xc = range(1, numEpochs + 1) xv = [] for i in xc: if (i % evalInterval == 0): xv.append(i) plt.figure(1, figsize=(7, 5)) plt.plot(xc, train_loss) plt.plot(xv, val_loss) plt.xlabel('num of Epochs') plt.ylabel('loss') plt.title('train_loss vs val_loss') plt.grid(True) plt.legend(['train', 'val']) #print plt.style.available # use bmh, classic,ggplot for big pictures plt.style.use(['classic']) plt.savefig(modelFolder + "/lossCurve.png") plt.figure(2, figsize=(7, 5)) plt.plot(xc, train_acc) plt.plot(xv, val_acc) plt.xlabel('num of Epochs') plt.ylabel('accuracy') plt.title('train_acc vs val_acc') plt.grid(True) plt.legend(['train', 'val'], loc=4) #print plt.style.available # use bmh, classic,ggplot for big pictures plt.style.use(['classic']) plt.savefig(modelFolder + "/accuracyCurve.png") #plt.show() trainLogAcc.close() validationLogAcc.close() trainLogLoss.close() validationLogLoss.close() writer.export_scalars_to_json(modelFolder + "/all_scalars.json") writer.close() return bestmodel, validationAccuracy