Beispiel #1
0
def main_run(dataset, stage, root_dir, out_dir, stage1_dict, seqLen,
             trainBatchSize, numEpochs, lr1, decay_factor, decay_step, memSize,
             outPool_size, split, evalInterval, regression, rloss, debug):
    if debug:
        n_workers = 0
        n_workers_test = 0
        device = 'cpu'
    else:
        n_workers = 4
        n_workers_test = 2
        device = 'cuda'
    # Train/Validation/Test split
    train_splits = ["S1", "S3", "S4"]
    val_splits = ["S2"]

    test_split = split

    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]

    normalize = Normalize(mean=mean, std=std)

    stage = stage
    #test_split = split
    seqLen = seqLen
    memSize = memSize
    c_cam_classes = outPool_size
    dataset = dataset
    best_acc = 0

    if stage == 1:
        trainBatchSize = trainBatchSize
        testBatchSize = trainBatchSize
        lr1 = lr1
        decay_factor = decay_factor
        decay_step = decay_step
        numEpochs = numEpochs
    elif stage == 2 or stage == 3:
        trainBatchSize = trainBatchSize
        testBatchSize = trainBatchSize
        lr1 = lr1
        decay_factor = decay_factor
        decay_step = decay_step
        numEpochs = numEpochs

    num_classes = 61

    dataset_dir = root_dir

    #model_folder = os.path.join('.', out_dir, dataset, str(test_split))
    model_folder = os.path.join('./', out_dir, 'stage' + str(stage))
    if not os.path.exists(model_folder):
        os.makedirs(model_folder)
    else:
        print('Directory {} exists!'.format(model_folder))
        sys.exit()

    note_fl = open(model_folder + '/note.txt', 'w')
    note_fl.write('Number of Epochs = {}\n'
                  'lr = {}\n'
                  'Train Batch Size = {}\n'
                  'Sequence Length = {}\n'
                  'Decay steps = {}\n'
                  'Decay factor = {}\n'
                  'Memory size = {}\n'
                  'Memory cam classes = {}\n'.format(numEpochs, lr1,
                                                     trainBatchSize, seqLen,
                                                     decay_step, decay_factor,
                                                     memSize, c_cam_classes))

    note_fl.close()

    # Log files
    writer = SummaryWriter(model_folder)
    train_log_loss = open((model_folder + '/train_log_loss.txt'), 'w')
    train_log_acc = open((model_folder + '/train_log_acc.txt'), 'w')
    train_log_loss_batch = open((model_folder + '/train_log_loss_batch.txt'),
                                'w')
    test_log_loss = open((model_folder + '/test_log_loss.txt'), 'w')
    test_log_acc = open((model_folder + '/test_log_acc.txt'), 'w')

    # Dataloaders
    spatial_transform = Compose([
        Scale(256),
        RandomHorizontalFlip(),
        MultiScaleCornerCrop([1, 0.875, 0.75, 0.65625], 224),
        ToTensor(), normalize
    ])

    print('Preparing dataset...')
    # Data loader
    normalize = Normalize(mean=[0.485, 0.456, 0.406],
                          std=[0.229, 0.224, 0.225])
    spatial_transform = Compose([
        Scale(256),
        RandomHorizontalFlip(),
        MultiScaleCornerCrop([1, 0.875, 0.75, 0.65625], 224),
        # ToTensor(),
        # normalize
    ])
    transform_rgb = Compose([ToTensor(), normalize])
    transform_MS = Compose([Resize((7, 7)), ToTensor()])

    vid_seq_train = makeDataset(dataset_dir,
                                splits=train_splits,
                                spatial_transform=spatial_transform,
                                transform_rgb=transform_rgb,
                                transform_MS=transform_MS,
                                seqLen=seqLen,
                                fmt='.png',
                                regression=regression)

    train_loader = torch.utils.data.DataLoader(vid_seq_train,
                                               batch_size=trainBatchSize,
                                               shuffle=True,
                                               num_workers=n_workers,
                                               pin_memory=True)

    vid_seq_test = makeDataset(dataset_dir,
                               splits=val_splits,
                               spatial_transform=Compose(
                                   [Scale(256), CenterCrop(224)]),
                               transform_rgb=transform_rgb,
                               transform_MS=transform_MS,
                               seqLen=seqLen,
                               fmt='.png',
                               regression=regression,
                               verbose=False)

    test_loader = torch.utils.data.DataLoader(vid_seq_test,
                                              batch_size=testBatchSize,
                                              shuffle=False,
                                              num_workers=n_workers,
                                              pin_memory=True)

    print('here')
    print('Number of train samples = {}'.format(vid_seq_train.__len__()))

    print('Number of test samples = {}'.format(vid_seq_test.__len__()))

    train_params = []
    if stage == 1:
        if regression:
            model = attentionModel(num_classes=num_classes,
                                   mem_size=memSize,
                                   n_channels=1)
        else:
            model = attentionModel(num_classes=num_classes, mem_size=memSize)
        model.train(False)
        for params in model.parameters():
            params.requires_grad = False
    elif stage == 2 or stage == 3:
        if regression:
            model = attentionModel(num_classes=num_classes,
                                   mem_size=memSize,
                                   n_channels=1,
                                   c_cam_classes=c_cam_classes)
        else:
            model = attentionModel(num_classes=num_classes,
                                   mem_size=memSize,
                                   c_cam_classes=c_cam_classes)

        #model = attentionModel(num_classes=num_classes, mem_size=memSize, c_cam_classes=c_cam_classes)
        if stage == 2:
            checkpoint_path = os.path.join(
                stage1_dict, 'last_checkpoint_stage' + str(1) + '.pth.tar')
        elif stage == 3:
            checkpoint_path = os.path.join(
                stage1_dict, 'last_checkpoint_stage' + str(2) + '.pth.tar')
        if os.path.exists(checkpoint_path):
            print('Loading weights from checkpoint file {}'.format(
                checkpoint_path))
        else:
            print('Checkpoint file {} does not exist'.format(checkpoint_path))
            sys.exit()
        last_checkpoint = torch.load(checkpoint_path)
        model.load_state_dict(last_checkpoint['model_state_dict'],
                              strict=False)
        model.train(False)
        for params in model.parameters():
            params.requires_grad = False

        for params in model.resNet.layer4[0].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[0].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[1].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[1].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[2].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[2].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.fc.parameters():
            params.requires_grad = True
            train_params += [params]

        # Add params from ms_module
        if stage == 2:
            for params in model.ms_module.parameters():
                params.requires_grad = True
                train_params += [params]

    for params in model.lsta_cell.parameters():
        params.requires_grad = True
        train_params += [params]

    for params in model.classifier.parameters():
        params.requires_grad = True
        train_params += [params]

    model.classifier.train(True)

    model.ms_module.train(True)
    model.to(device)

    loss_fn = nn.CrossEntropyLoss()

    if regression:
        if rloss == 'MSE':
            # Mean Squared Error loss
            loss_ms_fn = nn.MSELoss()  # it should work
        elif rloss == 'L1':
            # L1 loss
            loss_ms_fn = nn.L1Loss()
        elif rloss == 'SmoothL1':
            # Huber Loss or Smooth L1 Loss
            loss_ms_fn = nn.SmoothL1Loss()
        elif rloss == 'KLdiv':
            # Kullback-Leiber Loss
            loss_ms_fn = nn.KLDivLoss()
    else:
        # classification
        loss_ms_fn = nn.CrossEntropyLoss()  # TODO: check paper Planamente

    optimizer_fn = torch.optim.Adam(train_params,
                                    lr=lr1,
                                    weight_decay=5e-4,
                                    eps=1e-4)

    optim_scheduler = torch.optim.lr_scheduler.MultiStepLR(
        optimizer_fn, milestones=decay_step, gamma=decay_factor)

    train_iter = 0

    for epoch in range(numEpochs):
        #optim_scheduler.step()
        epoch_loss = 0
        numCorrTrain = 0
        trainSamples = 0
        iterPerEpoch = 0
        # model.classifier.train(True)
        model.lsta_cell.train(True)
        model.classifier.train(True)
        if stage == 2:
            model.resNet.layer4[0].conv1.train(True)
            model.resNet.layer4[0].conv2.train(True)
            model.resNet.layer4[1].conv1.train(True)
            model.resNet.layer4[1].conv2.train(True)
            model.resNet.layer4[2].conv1.train(True)
            model.resNet.layer4[2].conv2.train(True)
            model.resNet.fc.train(True)
            model.ms_module.train(True)

        writer.add_scalar('lr', optimizer_fn.param_groups[0]['lr'], epoch + 1)
        for i, (inputs, inputsMS, targets) in enumerate(train_loader):
            # Inputs:
            #   - inputsRGB : the rgb frame input
            # Labels :
            #   - inputsMS  : the motion task label
            #   - targets   : output

            train_iter += 1
            iterPerEpoch += 1
            optimizer_fn.zero_grad()
            inputVariable = inputs.permute(1, 0, 2, 3, 4).to(device)
            labelVariable = targets.to(device)
            msVariable = inputsMS.to(device)
            trainSamples += inputs.size(0)
            output_label, _, output_ms = model(inputVariable, device)
            loss_c = loss_fn(output_label, labelVariable)
            if stage == 2:
                if regression:
                    msVariable = torch.reshape(
                        msVariable, (seqLen * 7 * 7, msVariable.size(0)))
                    output_ms = torch.sigmoid(output_ms)
                    output_ms = torch.reshape(
                        output_ms, (seqLen * 7 * 7, output_ms.size(0)))
                else:
                    # classification task
                    msVariable = torch.reshape(
                        msVariable,
                        (seqLen * 7 * 7, msVariable.size(0))).long()
                    output_ms = torch.reshape(
                        output_ms, (seqLen * 7 * 7, 2, output_ms.size(0)))
                loss_ms = loss_ms_fn(output_ms, msVariable)
                loss = loss_c + loss_ms
            else:
                loss = loss_c
            loss.backward()
            optimizer_fn.step()
            _, predicted = torch.max(output_label.data, 1)
            numCorrTrain += (predicted == targets.to(device)).sum()
            #print('Training loss after {} iterations = {} '.format(train_iter, loss.data.item()))
            #train_log_loss_batch.write('Training loss after {} iterations = {}\n'.format(train_iter, loss.data.item()))
            #writer.add_scalar('train/iter_loss', loss.data.item(), train_iter)
            epoch_loss += loss.data.item()
        avg_loss = epoch_loss / iterPerEpoch
        trainAccuracy = (numCorrTrain / trainSamples) * 100
        print('Average training loss after {} epoch = {} '.format(
            epoch + 1, avg_loss))
        print('Training accuracy after {} epoch = {}% '.format(
            epoch + 1, trainAccuracy))
        writer.add_scalar('train/epoch_loss', avg_loss, epoch + 1)
        writer.add_scalar('train/accuracy', trainAccuracy, epoch + 1)
        train_log_loss.write('Training loss after {} epoch = {}\n'.format(
            epoch + 1, avg_loss))
        train_log_acc.write('Training accuracy after {} epoch = {}\n'.format(
            epoch + 1, trainAccuracy))

        save_path_model = os.path.join(
            model_folder, 'last_checkpoint_stage' + str(stage) + '.pth.tar')
        save_file = {
            'epoch': epoch + 1,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer_fn.state_dict(),
            'best_acc': best_acc,
        }
        torch.save(save_file, save_path_model)

        if (epoch + 1) % evalInterval == 0:
            #print('Testing...')
            model.train(False)
            test_loss_epoch = 0
            test_iter = 0
            test_samples = 0
            numCorr = 0
            for j, (inputs, inputsMS, targets) in enumerate(test_loader):
                #print('testing inst = {}'.format(j))
                test_iter += 1
                test_samples += inputs.size(0)
                inputVariable = inputs.permute(1, 0, 2, 3, 4).to(device)
                labelVariable = targets.to(device)
                msVariable = inputsMS.to(device)

                output_label, _, output_ms = model(inputVariable, device)
                test_loss_c = loss_fn(output_label, labelVariable)
                if stage == 2:
                    if regression:
                        msVariable = torch.reshape(
                            msVariable, (seqLen * 7 * 7, msVariable.size(0)))
                        output_ms = torch.sigmoid(output_ms)
                        output_ms = torch.reshape(
                            output_ms, (seqLen * 7 * 7, output_ms.size(0)))
                    else:
                        # classification task
                        msVariable = torch.reshape(
                            msVariable,
                            (seqLen * 7 * 7, msVariable.size(0))).long()
                        output_ms = torch.reshape(
                            output_ms, (seqLen * 7 * 7, 2, output_ms.size(0)))
                    test_loss_ms = loss_ms_fn(output_ms, msVariable)
                    test_loss = test_loss_c + test_loss_ms
                else:
                    test_loss = test_loss_c
                test_loss_epoch += test_loss.data.item()
                _, predicted = torch.max(output_label.data, 1)
                numCorr += (predicted == targets.to(device)).sum()
            test_accuracy = (numCorr / test_samples) * 100
            avg_test_loss = test_loss_epoch / test_iter
            print('Test Loss after {} epochs, loss = {}'.format(
                epoch + 1, avg_test_loss))
            print('Test Accuracy after {} epochs = {}%'.format(
                epoch + 1, test_accuracy))
            writer.add_scalar('test/epoch_loss', avg_test_loss, epoch + 1)
            writer.add_scalar('test/accuracy', test_accuracy, epoch + 1)
            test_log_loss.write('Test Loss after {} epochs = {}\n'.format(
                epoch + 1, avg_test_loss))
            test_log_acc.write('Test Accuracy after {} epochs = {}%\n'.format(
                epoch + 1, test_accuracy))

            if test_accuracy > best_acc:
                best_acc = test_accuracy
                save_path_model = os.path.join(
                    model_folder,
                    'best_checkpoint_stage' + str(stage) + '.pth.tar')
                save_file = {
                    'epoch': epoch + 1,
                    'model_state_dict': model.state_dict(),
                    'optimizer_state_dict': optimizer_fn.state_dict(),
                    'best_acc': best_acc,
                }
                torch.save(save_file, save_path_model)
        optim_scheduler.step()
    train_log_loss.close()
    train_log_acc.close()
    test_log_acc.close()
    train_log_loss_batch.close()
    test_log_loss.close()
    writer.export_scalars_to_json(model_folder + "/all_scalars.json")
    writer.close()
Beispiel #2
0
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 = makeDataset(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)
    trainLoader = torch.utils.data.DataLoader(vidSeqTrain,
                                              batch_size=trainBatchSize,
                                              shuffle=True,
                                              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 = makeDataset(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)
    testLoader = torch.utils.data.DataLoader(vidSeqTest,
                                             batch_size=testBatchSize,
                                             shuffle=False,
                                             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):
        if epoch != 0:
            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())
            inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4))
            # labelVariable = Variable(targets.cuda())
            print(inputVariable1.shape)
            labelVariable = Variable(targets)
            # print("labelVariable")
            # print(labelVariable)
            # print("targets")
            # print(targets)
            outputLabel = model(inputVariable1)
            # print("outputs")
            # print(outputLabel)
            loss = lossFn(outputLabel, labelVariable)

            loss.backward()
            optimizerFn.step()
            outputProb = torch.nn.Softmax(dim=1)(outputLabel)
            # print("outputProb.data going into torch.max ")
            # print(outputProb.data)
            _, predicted = torch.max(outputProb.data, 1)
            # numCorrTrain += (predicted == targets.cuda()).sum()
            # print("predicted")
            # print(predicted)
            numCorrTrain += (predicted == targets).sum()
            # epochLoss += loss.data[0]
            # print(numCorrTrain)
            epochLoss += loss.data.item()
        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)
                    inputVariable1 = Variable(inputs.permute(1, 0, 2, 3, 4),
                                              volatile=True)
                else:
                    # inputVariable1 = Variable(inputs[0].cuda(), volatile=True)
                    inputVariable1 = Variable(inputs[0], volatile=True)
                # labelVariable = Variable(targets.cuda(async =True), volatile=True)
                labelVariable = Variable(targets)
                outputLabel = model(inputVariable1)
                outputLabel_mean = torch.mean(outputLabel, 0, True)
                testLoss = lossFn(outputLabel_mean, labelVariable)
                testLossEpoch += testLoss.data.item()
                _, 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
Beispiel #3
0
# transform_test = transforms.Compose([
#     transforms.ToTensor(),
#     transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),
# ])
data_path = args.datapath
seqLen=args.seqLen
testBatchSize=1

trainX, trainY, testX, testY = make_split(data_path)
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(trainX, trainY, spatial_transform=spatial_transform,
                                seqLen=seqLen)

trainLoader = torch.utils.data.DataLoader(vidSeqTrain, batch_size=args.trainBatchSize,
                            shuffle=True, num_workers=0)

test_spatial_transform = Compose([Scale(256), CenterCrop(224), FlippedImagesTest(mean=mean, std=std)])

vidSeqTest = makeDataset(testX, testY, seqLen=seqLen,
    spatial_transform=test_spatial_transform)

testLoader = torch.utils.data.DataLoader(vidSeqTest, batch_size=testBatchSize,
                        shuffle=False, num_workers=1)

# trainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)
# trainLoader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)
Beispiel #4
0
def main_run(dataset, root_dir, checkpoint_path, seqLen, testBatchSize, memSize, outPool_size, split):


    mean=[0.485, 0.456, 0.406]
    std=[0.229, 0.224, 0.225]

    normalize = Normalize(mean=mean, std=std)

    test_split = split
    seqLen = seqLen
    memSize = memSize
    c_cam_classes = outPool_size
    dataset = dataset
    testBatchSize = testBatchSize
    checkpoint_path = checkpoint_path

    if dataset == 'gtea_61':
        num_classes = 61
    elif dataset == 'gtea_71':
        num_classes = 71
    elif dataset == 'egtea_gaze+':
        num_classes = 106
    else:
        print('Wrong dataset')
        sys.exit()
    dataset_dir = os.path.join(root_dir, dataset)
    print('Preparing dataset...')

    if dataset == 'egtea_gaze+':
        trainDatasetF, testDatasetF, trainLabels, testLabels, trainNumFrames, testNumFrames = gen_split_egtea_gazePlus(dataset_dir,
                                                                                                               test_split)
    else:
        trainDatasetF, testDatasetF, trainLabels, testLabels, trainNumFrames, testNumFrames, _ = gen_split(dataset_dir,
                                                                                                  test_split)


    vid_seq_test = makeDataset(testDatasetF, testLabels, testNumFrames,
                               spatial_transform=Compose([Scale(256), CenterCrop(224), ToTensor(), normalize]),
                               fmt='.jpg', seqLen=seqLen)

    print('Number of test samples = {}'.format(vid_seq_test.__len__()))

    print("Dataset shape: ", len(vid_seq_test.__getitem__(0)), vid_seq_test.__getitem__(0)[0].shape , end='\n\n\n')
    test_loader = torch.utils.data.DataLoader(vid_seq_test, batch_size=testBatchSize,
                            shuffle=False, num_workers=0, pin_memory=True)


    model = attentionModel(num_classes=num_classes, mem_size=memSize, c_cam_classes=c_cam_classes)
    if os.path.exists(checkpoint_path):
            print('Loading weights from checkpoint file {}'.format(checkpoint_path))
    else:
            print('Checkpoint file {} does not exist'.format(checkpoint_path))
            sys.exit()
    last_checkpoint = torch.load(checkpoint_path) #, map_location=torch.device('cpu'))
    model.load_state_dict(last_checkpoint['model_state_dict'])
    model.cuda()
    model.train(False)
    model.eval()

    print('Testing...')
    test_iter = 0
    test_samples = 0
    numCorr = 0
    for j, (inputs, targets) in tqdm(enumerate(test_loader)):
        test_iter += 1
        test_samples += inputs.size(0)
        with torch.no_grad():
            print(inputs.shape, targets.shape)
            inputVariable = Variable(inputs.permute(1, 0, 2, 3, 4).cuda())
            output_label, _ = model(inputVariable)
            del inputVariable
            _, predicted = torch.max(output_label.data, 1)
            numCorr += (predicted == targets.cuda()).sum()
    test_accuracy = (numCorr.cpu().item() / test_samples) * 100
    print('Test Accuracy after = {}%'.format(test_accuracy))
Beispiel #5
0
def main_run(version, flowModel, rgbModel, stackSize, seqLen, memSize, trainDatasetDir, outDir,
             trainBatchSize, valBatchSize, lr1, numEpochs, decay_step, decay_factor):
    
    num_classes = 61     # gtea61 dataset
    model_folder = os.path.join("./", outDir, version)

    # Create the dir
    print(f"Checking directory {model_folder}")
    if os.path.exists(model_folder):
        print('Dir {} exists!'.format(model_folder))
        sys.exit()
    print(f"Creating directory{model_folder}")
    os.makedirs(model_folder)

    # Log files
    print(f"Creating log files")
    train_log_loss = open((model_folder + '/train_log_loss.txt'), 'w')
    train_log_acc = open((model_folder + '/train_log_acc.txt'), 'w')
    val_log_loss = open((model_folder + '/val_log_loss.txt'), 'w')
    val_log_acc = open((model_folder + '/val_log_acc.txt'), 'w')

    # ImageNet mean and std
    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]

    # Train val partitioning
    train_usr = ["S1", "S3", "S4"]
    val_usr = ["S2"]


    normalize = Normalize(mean=mean, std=std)

    spatial_transform = Compose([Scale(256), RandomHorizontalFlip(), MultiScaleCornerCrop([1, 0.875, 0.75, 0.65625], 224),
                                 ToTensor(), normalize])
    # train dataset
    print(f"Defining train dataset")
    vid_seq_train = makeDataset(trainDatasetDir, train_usr, spatial_transform,
                               stackSize=stackSize, seqLen=seqLen)

    train_loader = torch.utils.data.DataLoader(vid_seq_train, batch_size=trainBatchSize,
                            shuffle=True, num_workers=4, pin_memory=True)
    

    # val dataset
    print(f"Defining validation dataset")
    vid_seq_val = makeDataset(trainDatasetDir, val_usr,
                                   spatial_transform=Compose([Scale(256), CenterCrop(224), ToTensor(), normalize]),
                                   stackSize=stackSize, phase="val", seqLen=seqLen)
    
    val_loader = torch.utils.data.DataLoader(vid_seq_val, batch_size=valBatchSize,
                                shuffle=False, num_workers=2, pin_memory=True)
    
    valSamples = vid_seq_val.__len__()


    # model
    print("Building model")
    model = twoStreamAttentionModel(flowModel=flowModel, frameModel=rgbModel, stackSize=stackSize, memSize=memSize,         # see twoStreamModel.py
                                    num_classes=num_classes)
    
    print("Setting trainable parameters")
    for params in model.parameters():           # initially freeze all layers
        params.requires_grad = False

    model.train(False)
    train_params = []

    for params in model.classifier.parameters():    # unfreeze classifier layer (the layer that joins the two models outputs)
        params.requires_grad = True
        train_params += [params]

    for params in model.frameModel.lstm_cell.parameters():  # unfreeze lstm layer of the frame model
        train_params += [params]
        params.requires_grad = True

    for params in model.frameModel.resNet.layer4[0].conv1.parameters():     #unfreeze layer 4
        params.requires_grad = True
        train_params += [params]

    for params in model.frameModel.resNet.layer4[0].conv2.parameters():
        params.requires_grad = True
        train_params += [params]

    for params in model.frameModel.resNet.layer4[1].conv1.parameters():
        params.requires_grad = True
        train_params += [params]

    for params in model.frameModel.resNet.layer4[1].conv2.parameters():
        params.requires_grad = True
        train_params += [params]

    for params in model.frameModel.resNet.layer4[2].conv1.parameters():
        params.requires_grad = True
        train_params += [params]
    #
    for params in model.frameModel.resNet.layer4[2].conv2.parameters():
        params.requires_grad = True
        train_params += [params]
    #
    for params in model.frameModel.resNet.fc.parameters():              # unfreeze last fully connected layer of frame model 
        params.requires_grad = True                                     # (I still don't know why, because in the joining of the two models, this layer is skipped)
        train_params += [params]                                        

    base_params = []
    for params in model.flowModel.layer4.parameters():              # unfreeze layer 4 of flow model
        base_params += [params]
        params.requires_grad = True

    print("Moving model to GPU")
    model.to(DEVICE)

    trainSamples = vid_seq_train.__len__()
    min_accuracy = 0

    print("Defining loss function, optimizer and scheduler")
    loss_fn = nn.CrossEntropyLoss()     # loss function
    optimizer_fn = torch.optim.SGD([    # optimizer
        {'params': train_params},
        {'params': base_params, 'lr': 1e-4},  # 1e-4
    ], lr=lr1, momentum=0.9, weight_decay=5e-4)

    #scheduler
    optim_scheduler = torch.optim.lr_scheduler.StepLR(optimizer_fn, step_size=decay_step, gamma=decay_factor)
    train_iter = 0

    print("Training begun")
    # TRAIN PROCEDURE
    for epoch in range(numEpochs):
        optim_scheduler.step()
        epoch_loss = 0
        numCorrTrain = 0
        iterPerEpoch = 0
        model.classifier.train(True)
        model.flowModel.layer4.train(True)


        start = time.time()
        for j, (inputFrame, inputMMaps, inputFlow, targets) in enumerate(train_loader):
            
            print(f"step {j} / {int(np.floor(trainSamples/trainBatchSize))}")
            
            train_iter += 1
            iterPerEpoch += 1
            optimizer_fn.zero_grad()                                                # put gradients to zero
            inputVariableFlow = Variable(inputFlow.to(DEVICE))
            inputVariableFrame = Variable(inputFrame.permute(1, 0, 2, 3, 4).to(DEVICE))
            labelVariable = Variable(targets.to(DEVICE))
            #print("predict")
            output_label = model(inputVariableFlow, inputVariableFrame)         # predict
            loss = loss_fn(F.log_softmax(output_label, dim=1), labelVariable)   # compute loss
            #print("backprop")
            loss.backward()                                                     
            optimizer_fn.step()
            #print("accuracy")
            _, predicted = torch.max(output_label.data, 1)                  
            numCorrTrain += (predicted == targets.to(DEVICE)).sum()             # counting number of correct predictions
            epoch_loss += loss.data.item()  

        
        avg_loss = epoch_loss / iterPerEpoch                                    # computing average per epoch loss
        trainAccuracy = (numCorrTrain.item() / trainSamples) * 100
        print('Average training loss after {} epoch = {} '.format(epoch + 1, avg_loss))
        print('Training accuracy after {} epoch = {}% '.format(epoch + 1, trainAccuracy))
        train_log_loss.write('Training loss after {} epoch = {}\n'.format(epoch + 1, avg_loss))             # log file
        train_log_acc.write('Training accuracy after {} epoch = {}\n'.format(epoch + 1, trainAccuracy))     # log file
        print(f"Elapsed : {time.time()-start}")

        # VALIDATION
        if (epoch + 1) % 5 == 0:
            model.train(False)
            val_loss_epoch = 0
            val_iter = 0
            numCorr = 0
            for j, (inputFrame, inputMMaps, inputFlow, targets) in enumerate(val_loader):
                if j % 1 == 0:
                    print(f"step {j} / {int(np.floor(vid_seq_val.__len__()/valBatchSize))}")

                val_iter += 1
                inputVariableFlow = Variable(inputFlow.to(DEVICE))
                inputVariableFrame = Variable(inputFrame.permute(1, 0, 2, 3, 4).to(DEVICE))
                labelVariable = Variable(targets.to(DEVICE))
                output_label = model(inputVariableFlow, inputVariableFrame)
                loss = loss_fn(F.log_softmax(output_label, dim=1), labelVariable)
                val_loss_epoch += loss.data.item()
                _, predicted = torch.max(output_label.data, 1)
                numCorr += (predicted == labelVariable.data).sum()
            val_accuracy = (numCorr.item() / valSamples) * 100
            avg_val_loss = val_loss_epoch / val_iter
            print('Val Loss after {} epochs, loss = {}'.format(epoch + 1, avg_val_loss))
            print('Val Accuracy after {} epochs = {}%'.format(epoch + 1, val_accuracy))
            val_log_loss.write('Val Loss after {} epochs = {}\n'.format(epoch + 1, avg_val_loss))       # log file
            val_log_acc.write('Val Accuracy after {} epochs = {}%\n'.format(epoch + 1, val_accuracy))   # log file
            if val_accuracy > min_accuracy:
                save_path_model = (model_folder + '/model_twoStream_state_dict.pth')                    # every epoch, check if the val accuracy is improved, if so, save that model
                torch.save(model.state_dict(), save_path_model)                                         # in that way, even if the model overfit, you will get always the best model
                min_accuracy = val_accuracy                                                             # in this way you don't have to care too much about the number of epochs

    train_log_loss.close()
    train_log_acc.close()
    val_log_acc.close()
    val_log_loss.close()
Beispiel #6
0
def main_run(dataset, stage, root_dir, out_dir, seqLen, trainBatchSize,
             numEpochs, lr1, decay_factor, decay_step, memSize, outPool_size,
             split, evalInterval):

    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]

    normalize = Normalize(mean=mean, std=std)

    stage = stage
    test_split = split
    seqLen = seqLen
    memSize = memSize
    c_cam_classes = outPool_size
    dataset = dataset
    best_acc = 0

    if stage == 1:
        trainBatchSize = trainBatchSize
        testBatchSize = trainBatchSize
        lr1 = lr1
        decay_factor = decay_factor
        decay_step = decay_step
        numEpochs = numEpochs
    elif stage == 2:
        trainBatchSize = trainBatchSize
        testBatchSize = trainBatchSize
        lr1 = lr1
        decay_factor = decay_factor
        decay_step = decay_step
        numEpochs = numEpochs

    if dataset == 'gtea_61':
        num_classes = 61
    elif dataset == 'gtea_71':
        num_classes = 71
    elif dataset == 'egtea_gaze+':
        num_classes = 106
    else:
        print('Wrong dataset')
        sys.exit()
    dataset_dir = os.path.join(root_dir, dataset)

    model_folder = os.path.join('.', out_dir, dataset, str(test_split))

    if not os.path.exists(model_folder):
        os.makedirs(model_folder)

    note_fl = open(model_folder + '/note.txt', 'w')
    note_fl.write('Number of Epochs = {}\n'
                  'lr = {}\n'
                  'Train Batch Size = {}\n'
                  'Sequence Length = {}\n'
                  'Decay steps = {}\n'
                  'Decay factor = {}\n'
                  'Memory size = {}\n'
                  'Memory cam classes = {}\n'.format(numEpochs, lr1,
                                                     trainBatchSize, seqLen,
                                                     decay_step, decay_factor,
                                                     memSize, c_cam_classes))

    note_fl.close()

    # Log files
    writer = SummaryWriter(model_folder)
    train_log_loss = open((model_folder + '/train_log_loss.txt'), 'w')
    train_log_acc = open((model_folder + '/train_log_acc.txt'), 'w')
    train_log_loss_batch = open((model_folder + '/train_log_loss_batch.txt'),
                                'w')
    test_log_loss = open((model_folder + '/test_log_loss.txt'), 'w')
    test_log_acc = open((model_folder + '/test_log_acc.txt'), 'w')

    spatial_transform = Compose([
        Scale(256),
        RandomHorizontalFlip(),
        MultiScaleCornerCrop([1, 0.875, 0.75, 0.65625], 224),
        ToTensor(), normalize
    ])

    print('Preparing dataset...')

    if dataset == 'egtea_gaze+':
        trainDatasetF, testDatasetF, trainLabels, testLabels, trainNumFrames, testNumFrames = gen_split_egtea_gazePlus(
            dataset_dir, test_split)
    else:
        trainDatasetF, testDatasetF, trainLabels, testLabels, trainNumFrames, testNumFrames, _ = gen_split(
            dataset_dir, test_split)

    vid_seq_train = makeDataset(trainDatasetF,
                                trainLabels,
                                trainNumFrames,
                                spatial_transform=spatial_transform,
                                fmt='.jpg',
                                seqLen=seqLen)

    print('Number of train samples = {}'.format(vid_seq_train.__len__()))

    train_loader = torch.utils.data.DataLoader(vid_seq_train,
                                               batch_size=trainBatchSize,
                                               num_workers=4,
                                               pin_memory=True)

    vid_seq_test = makeDataset(testDatasetF,
                               testLabels,
                               testNumFrames,
                               spatial_transform=Compose([
                                   Scale(256),
                                   CenterCrop(224),
                                   ToTensor(), normalize
                               ]),
                               fmt='.jpg',
                               seqLen=seqLen)

    print('Number of test samples = {}'.format(vid_seq_test.__len__()))

    test_loader = torch.utils.data.DataLoader(vid_seq_test,
                                              batch_size=testBatchSize,
                                              shuffle=False,
                                              num_workers=2,
                                              pin_memory=True)

    train_params = []
    if stage == 1:
        model = attentionModel(num_classes=num_classes,
                               mem_size=memSize,
                               c_cam_classes=c_cam_classes)
        model.train(False)
        for params in model.parameters():
            params.requires_grad = False
    elif stage == 2:
        model = attentionModel(num_classes=num_classes,
                               mem_size=memSize,
                               c_cam_classes=c_cam_classes)
        checkpoint_path = os.path.join(
            model_folder, 'last_checkpoint_stage' + str(1) + '.pth.tar')
        if os.path.exists(checkpoint_path):
            print('Loading weights from checkpoint file {}'.format(
                checkpoint_path))
        else:
            print('Checkpoint file {} does not exist'.format(checkpoint_path))
            sys.exit()
        last_checkpoint = torch.load(checkpoint_path)
        model.load_state_dict(last_checkpoint['model_state_dict'])
        model.train(False)
        for params in model.parameters():
            params.requires_grad = False

        for params in model.resNet.layer4[0].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[0].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[1].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[1].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[2].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[2].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.fc.parameters():
            params.requires_grad = True
            train_params += [params]

    for params in model.lsta_cell.parameters():
        params.requires_grad = True
        train_params += [params]

    for params in model.classifier.parameters():
        params.requires_grad = True
        train_params += [params]

    model.classifier.train(True)
    model.cuda()

    loss_fn = nn.CrossEntropyLoss()

    optimizer_fn = torch.optim.Adam(train_params,
                                    lr=lr1,
                                    weight_decay=5e-4,
                                    eps=1e-4)

    optim_scheduler = torch.optim.lr_scheduler.MultiStepLR(
        optimizer_fn, milestones=decay_step, gamma=decay_factor)

    train_iter = 0

    for epoch in range(numEpochs):
        optim_scheduler.step()
        epoch_loss = 0
        numCorrTrain = 0
        trainSamples = 0
        iterPerEpoch = 0
        model.classifier.train(True)
        writer.add_scalar('lr', optimizer_fn.param_groups[0]['lr'], epoch + 1)
        for i, (inputs, targets) in enumerate(train_loader):
            train_iter += 1
            iterPerEpoch += 1
            optimizer_fn.zero_grad()
            inputVariable = Variable(inputs.permute(1, 0, 2, 3, 4).cuda())
            labelVariable = Variable(targets.cuda())
            trainSamples += inputs.size(0)
            output_label, _ = model(inputVariable)
            loss = loss_fn(output_label, labelVariable)
            loss.backward()
            optimizer_fn.step()
            _, predicted = torch.max(output_label.data, 1)
            numCorrTrain += (predicted == targets.cuda()).sum()
            if train_iter % 10 == 0:
                print('Training loss after {} iterations = {} '.format(
                    train_iter, loss.data[0]))
                train_log_loss_batch.write(
                    'Training loss after {} iterations = {}\n'.format(
                        train_iter, loss.data[0]))
                writer.add_scalar('train/iter_loss', loss.data[0], train_iter)
            epoch_loss += loss.data[0]
        avg_loss = epoch_loss / iterPerEpoch
        trainAccuracy = (numCorrTrain / trainSamples) * 100
        print('Average training loss after {} epoch = {} '.format(
            epoch + 1, avg_loss))
        print('Training accuracy after {} epoch = {}% '.format(
            epoch + 1, trainAccuracy))
        writer.add_scalar('train/epoch_loss', avg_loss, epoch + 1)
        writer.add_scalar('train/accuracy', trainAccuracy, epoch + 1)
        train_log_loss.write('Training loss after {} epoch = {}\n'.format(
            epoch + 1, avg_loss))
        train_log_acc.write('Training accuracy after {} epoch = {}\n'.format(
            epoch + 1, trainAccuracy))

        save_path_model = os.path.join(
            model_folder, 'last_checkpoint_stage' + str(stage) + '.pth.tar')
        save_file = {
            'epoch': epoch + 1,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer_fn.state_dict(),
            'best_acc': best_acc,
        }
        torch.save(save_file, save_path_model)

        if (epoch + 1) % evalInterval == 0:
            print('Testing...')
            model.train(False)
            test_loss_epoch = 0
            test_iter = 0
            test_samples = 0
            numCorr = 0
            for j, (inputs, targets) in enumerate(test_loader):
                print('testing inst = {}'.format(j))
                test_iter += 1
                test_samples += inputs.size(0)
                inputVariable = Variable(inputs.permute(1, 0, 2, 3, 4).cuda(),
                                         volatile=True)
                labelVariable = Variable(targets.cuda(async=True),
                                         volatile=True)
                output_label, _ = model(inputVariable)
                test_loss = loss_fn(output_label, labelVariable)
                test_loss_epoch += test_loss.data[0]
                _, predicted = torch.max(output_label.data, 1)
                numCorr += (predicted == targets.cuda()).sum()
            test_accuracy = (numCorr / test_samples) * 100
            avg_test_loss = test_loss_epoch / test_iter
            print('Test Loss after {} epochs, loss = {}'.format(
                epoch + 1, avg_test_loss))
            print('Test Accuracy after {} epochs = {}%'.format(
                epoch + 1, test_accuracy))
            writer.add_scalar('test/epoch_loss', avg_test_loss, epoch + 1)
            writer.add_scalar('test/accuracy', test_accuracy, epoch + 1)
            test_log_loss.write('Test Loss after {} epochs = {}\n'.format(
                epoch + 1, avg_test_loss))
            test_log_acc.write('Test Accuracy after {} epochs = {}%\n'.format(
                epoch + 1, test_accuracy))

            if test_accuracy > best_acc:
                best_acc = test_accuracy
                save_path_model = os.path.join(
                    model_folder,
                    'best_checkpoint_stage' + str(stage) + '.pth.tar')
                save_file = {
                    'epoch': epoch + 1,
                    'model_state_dict': model.state_dict(),
                    'optimizer_state_dict': optimizer_fn.state_dict(),
                    'best_acc': best_acc,
                }
                torch.save(save_file, save_path_model)

    train_log_loss.close()
    train_log_acc.close()
    test_log_acc.close()
    train_log_loss_batch.close()
    test_log_loss.close()
    writer.export_scalars_to_json(model_folder + "/all_scalars.json")
    writer.close()
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 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
Beispiel #9
0
DEVICE = 'cuda'

#dict_path = "/content/gdrive/My Drive/FINAL_LOGS/two_stream_300flow_16frames/model_twoStream_state_dict.pth"
dict_path = "/content/gdrive/My Drive/Lorenzo/ego-rnn-two-in-one/results/rgb_16frames_two_in_one_no_ms/model_rgb_state_dict.pth"
#dict_path = "/content/gdrive/My Drive/FINAL_LOGS/200+150epochs_RGB_16frames/test_2/model_rgb_state_dict.pth"
#dict_path = "/content/gdrive/My Drive/Lorenzo/ego-rnn-ss-task/rgb_16frames_regression_kl/model_rgb_state_dict.pth"
#dict_path = "/content/gdrive/My Drive/FINAL_LOGS/flow300/model_flow_state_dict.pth"

normalize = Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
spatial_transform = Compose(
    [Scale(256), CenterCrop(224),
     ToTensor(), normalize])

dataset = makeDataset("/content", ["S2"],
                      spatial_transform=spatial_transform,
                      seqLen=16,
                      phase="train")

loader = torch.utils.data.DataLoader(dataset,
                                     batch_size=1,
                                     shuffle=False,
                                     num_workers=2,
                                     pin_memory=True)

#model = twoStreamAttentionModel(flowModel="", frameModel="", stackSize=5, memSize=512, num_classes=61)
model = attentionModel(num_classes=61, mem_size=512)
#model = flow_resnet34(True, channels=2 * 5, num_classes=61)

model.load_state_dict(torch.load(dict_path), strict=True)
model.to(DEVICE)
model.train(False)
Beispiel #10
0
def main_run(dataset, stage, root_dir, out_dir, seqLen, trainBatchSize,
             numEpochs, lr1, decay_factor, decay_step, memSize, outPool_size,
             split, evalInterval, debug):
    if debug:
        n_workers = 0
        n_workers_test = 0
        device = 'cpu'
    else:
        n_workers = 4
        n_workers_test = 2
        device = 'cuda'
    # Train/Validation/Test split
    train_splits = ["S1", "S3", "S4"]
    val_splits = ["S2"]

    test_split = split

    mean = [0.485, 0.456, 0.406]
    std = [0.229, 0.224, 0.225]

    normalize = Normalize(mean=mean, std=std)

    stage = stage
    #test_split = split
    seqLen = seqLen
    memSize = memSize
    c_cam_classes = outPool_size
    dataset = dataset
    best_acc = 0

    if stage == 1:
        trainBatchSize = trainBatchSize
        testBatchSize = trainBatchSize
        lr1 = lr1
        decay_factor = decay_factor
        decay_step = decay_step
        numEpochs = numEpochs
    elif stage == 2:
        trainBatchSize = trainBatchSize
        testBatchSize = trainBatchSize
        lr1 = lr1
        decay_factor = decay_factor
        decay_step = decay_step
        numEpochs = numEpochs

    num_classes = 61

    dataset_dir = root_dir

    #model_folder = os.path.join('.', out_dir, dataset, str(test_split))
    model_folder = os.path.join('./', out_dir, dataset, 'LSTA',
                                'stage' + str(stage))
    if not os.path.exists(model_folder):
        os.makedirs(model_folder)
    else:
        print('Directory {} exists!'.format(model_folder))
        sys.exit()

    note_fl = open(model_folder + '/note.txt', 'w')
    note_fl.write('Number of Epochs = {}\n'
                  'lr = {}\n'
                  'Train Batch Size = {}\n'
                  'Sequence Length = {}\n'
                  'Decay steps = {}\n'
                  'Decay factor = {}\n'
                  'Memory size = {}\n'
                  'Memory cam classes = {}\n'.format(numEpochs, lr1,
                                                     trainBatchSize, seqLen,
                                                     decay_step, decay_factor,
                                                     memSize, c_cam_classes))

    note_fl.close()

    # Log files
    writer = SummaryWriter(model_folder)
    train_log_loss = open((model_folder + '/train_log_loss.txt'), 'w')
    train_log_acc = open((model_folder + '/train_log_acc.txt'), 'w')
    train_log_loss_batch = open((model_folder + '/train_log_loss_batch.txt'),
                                'w')
    test_log_loss = open((model_folder + '/test_log_loss.txt'), 'w')
    test_log_acc = open((model_folder + '/test_log_acc.txt'), 'w')

    spatial_transform = Compose([
        Scale(256),
        RandomHorizontalFlip(),
        MultiScaleCornerCrop([1, 0.875, 0.75, 0.65625], 224),
        ToTensor(), normalize
    ])

    vid_seq_train = makeDataset(root_dir,
                                train_splits,
                                spatial_transform=spatial_transform,
                                sequence=False,
                                numSeg=1,
                                fmt='.png',
                                seqLen=seqLen)

    train_loader = torch.utils.data.DataLoader(vid_seq_train,
                                               batch_size=trainBatchSize,
                                               shuffle=True,
                                               num_workers=n_workers,
                                               pin_memory=True)

    vid_seq_test = makeDataset(root_dir,
                               val_splits,
                               spatial_transform=Compose([
                                   Scale(256),
                                   CenterCrop(224),
                                   ToTensor(), normalize
                               ]),
                               sequence=False,
                               numSeg=1,
                               fmt='.png',
                               phase='test',
                               seqLen=seqLen)

    test_loader = torch.utils.data.DataLoader(vid_seq_test,
                                              batch_size=testBatchSize,
                                              shuffle=False,
                                              num_workers=n_workers_test,
                                              pin_memory=True)

    print('Number of train samples = {}'.format(vid_seq_train.__len__()))
    print('Number of test samples = {}'.format(vid_seq_test.__len__()))

    train_params = []
    if stage == 1:
        model = attentionModel(num_classes=num_classes,
                               mem_size=memSize,
                               c_cam_classes=c_cam_classes)
        model.train(False)
        for params in model.parameters():
            params.requires_grad = False
    elif stage == 2:
        model = attentionModel(num_classes=num_classes,
                               mem_size=memSize,
                               c_cam_classes=c_cam_classes)
        checkpoint_path = os.path.join(
            model_folder, 'last_checkpoint_stage' + str(1) + '.pth.tar')
        if os.path.exists(checkpoint_path):
            print('Loading weights from checkpoint file {}'.format(
                checkpoint_path))
        else:
            print('Checkpoint file {} does not exist'.format(checkpoint_path))
            sys.exit()
        last_checkpoint = torch.load(checkpoint_path)
        model.load_state_dict(last_checkpoint['model_state_dict'])
        model.train(False)
        for params in model.parameters():
            params.requires_grad = False

        for params in model.resNet.layer4[0].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[0].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[1].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[1].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[2].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[2].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.fc.parameters():
            params.requires_grad = True
            train_params += [params]

        # 2in1 stream
        for params in model.resNet.cond.parameters():
            params.requires_grad = True
            train_params += [params]

        # motion modulation layer
        for params in model.resNet.sft.parameters():
            params.requires_grad = True
            train_params += [params]

    for params in model.lsta_cell.parameters():
        params.requires_grad = True
        train_params += [params]

    for params in model.classifier.parameters():
        params.requires_grad = True
        train_params += [params]

    model.classifier.train(True)
    model.to(device)

    loss_fn = nn.CrossEntropyLoss()

    optimizer_fn = torch.optim.Adam(train_params,
                                    lr=lr1,
                                    weight_decay=5e-4,
                                    eps=1e-4)

    optim_scheduler = torch.optim.lr_scheduler.MultiStepLR(
        optimizer_fn, milestones=decay_step, gamma=decay_factor)

    train_iter = 0

    for epoch in range(numEpochs):
        #optim_scheduler.step()
        epoch_loss = 0
        numCorrTrain = 0
        trainSamples = 0
        iterPerEpoch = 0
        model.classifier.train(True)
        writer.add_scalar('lr', optimizer_fn.param_groups[0]['lr'], epoch + 1)
        for i, (inputFlow, inputRGB, targets) in enumerate(train_loader):
            train_iter += 1
            iterPerEpoch += 1
            optimizer_fn.zero_grad()
            inputVariable = inputRGB.permute(1, 0, 2, 3, 4).to(device)
            inputFlow = inputFlow.view(
                (inputFlow.shape[0], int(inputFlow.shape[1] / 2), 2,
                 inputFlow.shape[2], inputFlow.shape[3]))
            inputFlow = inputFlow.permute(1, 0, 2, 3, 4).to(device)
            labelVariable = targets.to(device)
            trainSamples += inputRGB.size(0)
            output_label, _ = model(inputVariable, inputFlow, device)
            loss = loss_fn(output_label, labelVariable)
            loss.backward()
            optimizer_fn.step()
            _, predicted = torch.max(output_label.data, 1)
            numCorrTrain += (predicted == targets.to(device)).sum()
            #print('Training loss after {} iterations = {} '.format(train_iter, loss.data.item()))
            #train_log_loss_batch.write('Training loss after {} iterations = {}\n'.format(train_iter, loss.data.item()))
            #writer.add_scalar('train/iter_loss', loss.data.item(), train_iter)
            epoch_loss += loss.data.item()
        avg_loss = epoch_loss / iterPerEpoch
        trainAccuracy = (numCorrTrain / trainSamples) * 100
        print('Average training loss after {} epoch = {} '.format(
            epoch + 1, avg_loss))
        print('Training accuracy after {} epoch = {}% '.format(
            epoch + 1, trainAccuracy))
        writer.add_scalar('train/epoch_loss', avg_loss, epoch + 1)
        writer.add_scalar('train/accuracy', trainAccuracy, epoch + 1)
        train_log_loss.write('Training loss after {} epoch = {}\n'.format(
            epoch + 1, avg_loss))
        train_log_acc.write('Training accuracy after {} epoch = {}\n'.format(
            epoch + 1, trainAccuracy))

        save_path_model = os.path.join(
            model_folder, 'last_checkpoint_stage' + str(stage) + '.pth.tar')
        save_file = {
            'epoch': epoch + 1,
            'model_state_dict': model.state_dict(),
            'optimizer_state_dict': optimizer_fn.state_dict(),
            'best_acc': best_acc,
        }
        torch.save(save_file, save_path_model)

        if (epoch + 1) % evalInterval == 0:
            #print('Testing...')
            model.train(False)
            test_loss_epoch = 0
            test_iter = 0
            test_samples = 0
            numCorr = 0
            for j, (inputFlow, inputRGB, targets) in enumerate(test_loader):
                #print('testing inst = {}'.format(j))
                test_iter += 1
                test_samples += inputRGB.size(0)
                inputVariable = inputRGB.permute(1, 0, 2, 3, 4).to(device)
                inputFlow = inputFlow.view(
                    (inputFlow.shape[0], int(inputFlow.shape[1] / 2), 2,
                     inputFlow.shape[2], inputFlow.shape[3]))
                inputFlow = inputFlow.permute(1, 0, 2, 3, 4).to(device)
                labelVariable = targets.to(device)
                output_label, _ = model(inputVariable, inputFlow, device)
                test_loss = loss_fn(output_label, labelVariable)
                test_loss_epoch += test_loss.data.item()
                _, predicted = torch.max(output_label.data, 1)
                numCorr += (predicted == targets.to(device)).sum()
            test_accuracy = (numCorr / test_samples) * 100
            avg_test_loss = test_loss_epoch / test_iter
            print('Test Loss after {} epochs, loss = {}'.format(
                epoch + 1, avg_test_loss))
            print('Test Accuracy after {} epochs = {}%'.format(
                epoch + 1, test_accuracy))
            writer.add_scalar('test/epoch_loss', avg_test_loss, epoch + 1)
            writer.add_scalar('test/accuracy', test_accuracy, epoch + 1)
            test_log_loss.write('Test Loss after {} epochs = {}\n'.format(
                epoch + 1, avg_test_loss))
            test_log_acc.write('Test Accuracy after {} epochs = {}%\n'.format(
                epoch + 1, test_accuracy))

            if test_accuracy > best_acc:
                best_acc = test_accuracy
                save_path_model = os.path.join(
                    model_folder,
                    'best_checkpoint_stage' + str(stage) + '.pth.tar')
                save_file = {
                    'epoch': epoch + 1,
                    'model_state_dict': model.state_dict(),
                    'optimizer_state_dict': optimizer_fn.state_dict(),
                    'best_acc': best_acc,
                }
                torch.save(save_file, save_path_model)
        optim_scheduler.step()
    train_log_loss.close()
    train_log_acc.close()
    test_log_acc.close()
    train_log_loss_batch.close()
    test_log_loss.close()
    writer.export_scalars_to_json(model_folder + "/all_scalars.json")
    writer.close()
Beispiel #11
0
def main_run(version, stage, train_data_dir, stage1_dict, out_dir, seqLen,
             trainBatchSize, valBatchSize, numEpochs, lr1, decay_factor,
             decay_step, mem_size):
    num_classes = 61

    model_folder = os.path.join("./", out_dir, version)

    if os.path.exists(model_folder):
        print('Directory {} exists!'.format(model_folder))
        sys.exit()
    os.makedirs(model_folder)

    train_log_loss = open((model_folder + '/train_log_loss.txt'), 'w')
    train_log_acc = open((model_folder + '/train_log_acc.txt'), 'w')
    val_log_loss = open((model_folder + '/val_log_loss.txt'), 'w')
    val_log_acc = open((model_folder + '/val_log_acc.txt'), 'w')

    # Train val partitioning
    train_usr = ["S1", "S3", "S4"]
    val_usr = ["S2"]

    # Data loader
    normalize = Normalize(mean=[0.485, 0.456, 0.406],
                          std=[0.229, 0.224, 0.225])
    spatial_transform = Compose([
        Scale(256),
        RandomHorizontalFlip(),
        MultiScaleCornerCrop([1, 0.875, 0.75, 0.65625], 224),
        ToTensor(), normalize
    ])

    vid_seq_train = makeDataset(train_data_dir,
                                train_usr,
                                spatial_transform=spatial_transform,
                                seqLen=seqLen)

    train_loader = torch.utils.data.DataLoader(vid_seq_train,
                                               batch_size=trainBatchSize,
                                               shuffle=True,
                                               num_workers=4,
                                               pin_memory=True)

    vid_seq_val = makeDataset(train_data_dir,
                              val_usr,
                              spatial_transform=Compose([
                                  Scale(256),
                                  CenterCrop(224),
                                  ToTensor(), normalize
                              ]),
                              seqLen=seqLen,
                              phase="test")

    val_loader = torch.utils.data.DataLoader(vid_seq_val,
                                             batch_size=valBatchSize,
                                             shuffle=False,
                                             num_workers=2,
                                             pin_memory=True)

    train_params = []

    # stage 1: train only lstm
    if stage == 1:

        model = attentionModel(num_classes=num_classes, mem_size=mem_size)
        model.train(False)
        for params in model.parameters():
            params.requires_grad = False

    # stage 2: train lstm, layer4, spatial attention and final fc
    if stage > 1:
        model = attentionModel(num_classes=num_classes, mem_size=mem_size)
        model.load_state_dict(torch.load(stage1_dict),
                              strict=False)  # pretrained
        model.train(False)
        for params in model.parameters():
            params.requires_grad = False
        #
        for params in model.resNet.layer4[0].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[0].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[1].conv1.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[1].conv2.parameters():
            params.requires_grad = True
            train_params += [params]

        for params in model.resNet.layer4[2].conv1.parameters():
            params.requires_grad = True
            train_params += [params]
        #
        for params in model.resNet.layer4[2].conv2.parameters():
            params.requires_grad = True
            train_params += [params]
        #
        for params in model.resNet.fc.parameters():  # fully connected layer
            params.requires_grad = True
            train_params += [params]

        model.resNet.layer4[0].conv1.train(True)
        model.resNet.layer4[0].conv2.train(True)
        model.resNet.layer4[1].conv1.train(True)
        model.resNet.layer4[1].conv2.train(True)
        model.resNet.layer4[2].conv1.train(True)
        model.resNet.layer4[2].conv2.train(True)
        model.resNet.fc.train(True)

        if stage == 2:
            # set to train the self supervised
            for params in model.ms_task.parameters():
                params.requires_grad = True
                train_params += [params]

        if stage == 3:
            # motion condition layer
            for params in model.resNet.condNet.parameters():
                params.requires_grad = True
                train_params += [params]

            # motion modulation layer
            for params in model.resNet.sft.parameters():
                params.requires_grad = True
                train_params += [params]

            # first convolution unfreeze
            for params in model.resNet.conv1.parameters():
                params.requires_grad = True
                train_params += [params]

    for params in model.lstm_cell.parameters(
    ):  # for both stages we train the lstm
        params.requires_grad = True
        train_params += [params]

    for params in model.classifier.parameters(
    ):  # for both stages we train the last classifier (after the lstm and avg pooling)
        params.requires_grad = True
        train_params += [params]

    model.lstm_cell.train(True)

    model.classifier.train(True)
    model.cuda()

    loss_fn = nn.CrossEntropyLoss()

    optimizer_fn = torch.optim.Adam(train_params,
                                    lr=lr1,
                                    weight_decay=4e-5,
                                    eps=1e-4)

    optim_scheduler = torch.optim.lr_scheduler.MultiStepLR(
        optimizer_fn, milestones=decay_step, gamma=decay_factor)

    train_iter = 0
    min_accuracy = 0

    for epoch in range(numEpochs):
        optim_scheduler.step()
        epoch_loss = 0
        epoch_ms_loss = 0
        numCorrTrain = 0
        trainSamples = 0
        iterPerEpoch = 0
        model.lstm_cell.train(True)
        model.classifier.train(True)
        if stage > 1:
            model.resNet.layer4[0].conv1.train(True)
            model.resNet.layer4[0].conv2.train(True)
            model.resNet.layer4[1].conv1.train(True)
            model.resNet.layer4[1].conv2.train(True)
            model.resNet.layer4[2].conv1.train(True)
            model.resNet.layer4[2].conv2.train(True)
            model.resNet.fc.train(True)

            if stage == 2:
                model.ms_task.conv.train(True)
                model.ms_task.fc.train(True)

            if stage == 3:
                # motion layers
                model.resNet.sft.train(True)
                model.resNet.condNet.train(True)
                model.resNet.conv1.train(True)

        start = time.time()
        for i, (inputFrame, inputMMaps, inputFlow,
                targets) in enumerate(train_loader):
            train_iter += 1
            iterPerEpoch += 1
            optimizer_fn.zero_grad()
            inputFrameVariable = Variable(
                inputFrame.permute(
                    1, 0, 2, 3,
                    4).to(DEVICE))  # sequence length as first dimension

            # flow data is reshaped to have x and y as channels
            inputFlow = inputFlow.view(
                (inputFlow.shape[0], int(inputFlow.shape[1] / 2), 2,
                 inputFlow.shape[2], inputFlow.shape[3]))
            inputFlowVariable = Variable(
                inputFlow.permute(
                    1, 0, 2, 3,
                    4).to(DEVICE))  # sequence length as first dimension

            labelVariable = Variable(targets.to(DEVICE))
            trainSamples += inputFrame.size(0)
            output_label, _, ms_lab = model(
                (inputFrameVariable, inputFlowVariable), stage)

            loss = loss_fn(output_label, labelVariable)

            if stage == 2:
                ms_loss = loss_ms_fn(F.softmax(ms_lab, dim=1),
                                     mmaps_preparation(inputMMaps, 1e-2))
                epoch_ms_loss += ms_loss.data.item()  #
                (loss + ms_loss).backward()
            else:
                loss.backward()

            optimizer_fn.step()
            _, predicted = torch.max(output_label.data, 1)
            numCorrTrain += (predicted == targets.to(
                DEVICE)).sum()  # evaluating number of correct classifications
            epoch_loss += loss.data.item()
        print(f"Elapsed {time.time() - start}")

        avg_loss = epoch_loss / iterPerEpoch
        if stage == 2:
            avg_ms_loss = epoch_ms_loss / iterPerEpoch  #

        trainAccuracy = (numCorrTrain.data.item() / trainSamples)

        train_log_loss.write('Training loss after {} epoch = {}\n'.format(
            epoch + 1, avg_loss))  # log file
        train_log_acc.write('Training accuracy after {} epoch = {}\n'.format(
            epoch + 1, trainAccuracy))  # log file
        print('Train: Epoch = {} | Loss = {} | Accuracy = {}'.format(
            epoch + 1, avg_loss, trainAccuracy))

        if stage == 2:
            train_log_loss.write(
                'Training ms loss after {} epoch = {}\n'.format(
                    epoch + 1, avg_ms_loss))  # log file
            print("ms avg epoch loss: {}".format(avg_ms_loss))

        if (epoch + 1) % VAL_FREQUENCY == 0:
            model.train(False)
            val_loss_epoch = 0
            val_ms_loss_epoch = 0
            val_iter = 0
            val_samples = 0
            numCorr = 0
            for j, (inputFrame, inputMMaps, inputFlow,
                    targets) in enumerate(val_loader):
                val_iter += 1
                val_samples += inputFrame.size(0)
                inputFrameVariable = Variable(
                    inputFrame.permute(1, 0, 2, 3, 4).to(DEVICE))

                # flow data is reshaped to have x and y as channels
                inputFlow = inputFlow.view(
                    (inputFlow.shape[0], int(inputFlow.shape[1] / 2), 2,
                     inputFlow.shape[2], inputFlow.shape[3]))
                inputFlowVariable = Variable(
                    inputFlow.permute(
                        1, 0, 2, 3,
                        4).to(DEVICE))  # sequence length as first dimension

                labelVariable = Variable(targets.to(DEVICE))
                output_label, _, ms_lab = model(
                    (inputFrameVariable, inputFlowVariable), stage)
                val_loss = loss_fn(output_label, labelVariable)
                val_loss_epoch += val_loss.data.item()

                if stage == 2:
                    ms_loss = loss_ms_fn(F.softmax(ms_lab, dim=1),
                                         mmaps_preparation(inputMMaps,
                                                           1e-2))  #
                    val_ms_loss_epoch += ms_loss.data.item()  #

                _, predicted = torch.max(output_label.data, 1)
                numCorr += (predicted == targets.to(DEVICE)).sum(
                )  # evaluating number of correct classifications
            val_accuracy = (numCorr.data.item() / val_samples)
            avg_val_loss = val_loss_epoch / val_iter
            avg_ms_loss = val_ms_loss_epoch / val_iter  #

            print('Val: Epoch = {} | Loss {} | Accuracy = {}'.format(
                epoch + 1, avg_val_loss, val_accuracy))
            val_log_loss.write('Val Loss after {} epochs = {}\n'.format(
                epoch + 1, avg_val_loss))  # log file
            val_log_acc.write('Val Accuracy after {} epochs = {}%\n'.format(
                epoch + 1, val_accuracy))  # log file

            if stage == 2:
                val_log_loss.write('Val ms loss after {} epoch = {}\n'.format(
                    epoch + 1, avg_ms_loss))  # log file
                print("Ms Epoch: {}".format(avg_ms_loss))

            if val_accuracy > min_accuracy:
                save_path_model = (
                    model_folder + '/model_rgb_state_dict.pth'
                )  # every epoch, check if the val accuracy is improved, if so, save that model
                torch.save(
                    model.state_dict(), save_path_model
                )  # in that way, even if the model overfit, you will get always the best model
                min_accuracy = val_accuracy  # in this way you don't have to care too much about the number of epochs

    train_log_loss.close()
    train_log_acc.close()
    val_log_acc.close()
    val_log_loss.close()