Beispiel #1
0
        #compute loss
        loss = criterion(outputs, labels)

        #backward
        loss.backward()
        optimizer.step()

        total_loss += loss.item()

        #print log
        if (i + 1) & 100 == 0:
            print("epoch {}/{} - step: {}/{} - loss: {:.4f}".format(
                epoch, num_epochs, i, num_steps, total_loss / (i + 1)))
    #----Validation----
    #set model to evaluating
    model.eval()

    val_losses = 0

    with torch.no_grad():
        correct = 0
        total = 0
        for _, (images, labels) in enumerate(val_loader):
            images, labels = images.to(device), labels.to(device)

            outputs = model(images)

            _, predicted = torch.max(outputs, 1)

            loss = criterion(outputs, labels)
Beispiel #2
0
def train(args):
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    print(device)
    renew_path(args.save)
    
    train_set = IkeaSet(TRAIN_MAT_PATH)
    train_loader = DataLoader(train_set, num_workers=4, pin_memory=True)

    test_set = IkeaSet(TEST_MAT_PATH)
    test_loader = DataLoader(test_set, num_workers=4, pin_memory=True)

    model = SimpleModel(n_class=len(train_set.classes)).to(device)
    model = load_model(model, 'model', args.save)
    
    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
    # learing rate scheduler
    lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.5)
    loss_fn = F.cross_entropy
    
    # training log
    training_log = {}
    training_log['args'] = []
    training_log['train_loss'] = []
    training_log['val_loss'] = []
    training_log['train_acc'] = []
    training_log['val_acc'] = []
    training_log['max_acc'] = 0.0

    for epoch in range(1, args.epoch + 1):
        time_a = datetime.datetime.now()
        model.train()
        average_loss = 0
        average_accuracy = 0
        for i, batch in enumerate(train_loader, 1):
            batch[0].to(device), batch[1].to(device)
            
            label = batch[1]
            label = label.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor)
            
            pred = model(batch[0])

            loss = loss_fn(pred, label)
            print(pred)
            print(torch.argmax(pred, dim=1), label)
            acc = get_accuracy(label, pred)
            if i % 20 == 0:
                print('epoch{}, {}/{}, lost={:.4f} acc={:.4f}'.format(epoch, i, len(train_loader), loss.item(), acc))
            average_loss = update_avg(i + 1, average_loss, loss.item())
            average_accuracy = update_avg(i + 1, average_accuracy, acc)

            #optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            lr_scheduler.step()

            embedding = None
            loss = None
            distanece = None
        
        model.eval()
        average_loss_val = 0
        average_accuracy_val = 0

        # evaluate after epoch.
        with torch.no_grad():
            for i, batch in enumerate(test_loader, 1):
                batch[0].to(device), batch[1].to(device)

                label = batch[1]
                #label = query_y.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor)
                label = label.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor)
                
                pred = model(batch[0])
                
                loss = loss_fn(pred, label)
                acc = get_accuracy(label, pred)
                average_loss_val = update_avg(i + 1, average_loss_val, loss.item())
                average_accuracy_val = update_avg(i + 1, average_accuracy_val, acc)

                embedding = None
                loss = None
                distanece = None

        print("epoch {} validation: loss={:4f} acc={:4f}".format(epoch, average_loss, average_accuracy))
        if average_accuracy > training_log['max_acc']:
            training_log['max_acc'] = acc
            save_model(model, 'max-acc', args.save)

        training_log['train_loss'].append(average_loss)
        training_log['train_acc'].append(average_accuracy)
        training_log['val_loss'].append(average_loss_val)
        training_log['val_acc'].append(average_accuracy_val)

        torch.save(training_log, os.path.join(args.save, 'training_log'))
        save_model(model, 'model', args.save)

        if epoch % 1 == 0:
            save_model(model, 'model', args.save)
        
        time_b = datetime.datetime.now()
        print('ETA:{}s/{}s'.format((time_b - time_a).seconds, (time_b - time_a).seconds * (args.epoch - epoch)))
def train(args):
    """
        Terminology: k-way n-shot, k classes, n shots per class
    """
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    print(device)
    renew_path(args.save)

    shots = args.shot + args.query
    train_set = IkeaSet(TRAIN_MAT_PATH)
    train_sampler = Sampler(train_set.label,
                            args.batch_num_train,
                            args.train_way,
                            shots,
                            limit_class=args.limit_class)
    train_loader = DataLoader(train_set,
                              batch_sampler=train_sampler,
                              num_workers=4,
                              pin_memory=True)

    test_set = IkeaSet(TEST_MAT_PATH)
    test_sampler = Sampler(test_set.label,
                           args.batch_num_test,
                           args.test_way,
                           shots,
                           limit_class=args.limit_class)
    test_loader = DataLoader(test_set,
                             batch_sampler=test_sampler,
                             num_workers=4,
                             pin_memory=True)

    model = SimpleModel().to(device)
    model = load_model(model, 'model', args.save)

    optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
    # learing rate scheduler
    lr_scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                                   step_size=20,
                                                   gamma=0.5)
    loss_fn = F.cross_entropy

    # training log
    training_log = {}
    training_log['args'] = []
    training_log['train_loss'] = []
    training_log['val_loss'] = []
    training_log['train_acc'] = []
    training_log['val_acc'] = []
    training_log['max_acc'] = 0.0

    for epoch in range(1, args.epoch + 1):
        time_a = datetime.datetime.now()
        model.train()
        average_loss = 0
        average_accuracy = 0
        print("Start epoch: ", epoch)
        for i, batch in enumerate(train_loader, 1):
            num = args.shot * args.train_way
            support_x, query_x = batch[0][:num].to(device), batch[0][num:].to(
                device)
            #support_y, query_y = batch[1][:num], batch[1][num:]
            #print(support_x.shape)
            embedding = model(support_x.float())

            # Get the mean of all the embeddings to get the prototype for a class
            embedding = embedding.reshape(args.shot, args.train_way,
                                          -1).mean(dim=0)
            #print(batch[0].shape)

            # Tough it seems strange here to just use labels in range but instead of real lables
            # , but that is beacause of the way the data was sampled (see sampled.py for structure
            # of a batch). The real label of the data does not correspond to the index of the closest
            # cluster center since the samples in the batch are shuffled, so instead we transform the data
            # label into the relative index in the range of classes, in this way the closest cluster
            # center index matches the relative index.
            label = torch.arange(args.train_way).repeat(args.query)
            #label = query_y.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor)
            label = label.type(torch.cuda.LongTensor if torch.cuda.
                               is_available() else torch.LongTensor)

            distance = euclidean(model(query_x), embedding)
            prob = F.softmax(distance, dim=1)

            loss = loss_fn(prob, label)
            acc = get_accuracy(label, prob)
            if i % 30 == 0:
                print(label.shape, distance.shape)
                print('epoch{}, {}/{}, lost={:.4f} acc={:.4f}'.format(
                    epoch, i, len(train_loader), loss.item(), acc))
            average_loss = update_avg(i + 1, average_loss, loss.item())
            average_accuracy = update_avg(i + 1, average_accuracy, acc)

            #optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            lr_scheduler.step()

            embedding = None
            loss = None
            distanece = None

        model.eval()
        average_loss_val = 0
        average_accuracy_val = 0

        # evaluate after epoch.
        with torch.no_grad():
            for i, batch in enumerate(test_loader, 1):
                num = args.shot * args.test_way
                support_x, query_x = batch[0][:num].to(
                    device), batch[0][num:].to(device)
                #support_y, query_y = batch[1][:num], batch[1][num:]
                embedding = model(support_x)
                embedding = embedding.reshape(args.shot, args.test_way,
                                              -1).mean(dim=0)

                label = torch.arange(args.train_way).repeat(args.query)
                #label = query_y.type(torch.cuda.LongTensor if torch.cuda.is_available() else torch.LongTensor)
                label = label.type(torch.cuda.LongTensor if torch.cuda.
                                   is_available() else torch.LongTensor)
                distance = euclidean(model(query_x), embedding)
                prob = F.softmax(distance, dim=1)

                loss = loss_fn(prob, label)
                acc = get_accuracy(label, prob)
                average_loss_val = update_avg(i + 1, average_loss_val,
                                              loss.item())
                average_accuracy_val = update_avg(i + 1, average_accuracy_val,
                                                  acc)

                embedding = None
                loss = None
                distanece = None

        print("epoch {} validation: loss={:4f} acc={:4f}".format(
            epoch, average_loss, average_accuracy))
        if average_accuracy > training_log['max_acc']:
            training_log['max_acc'] = acc
            save_model(model, 'max-acc', args.save)

        training_log['train_loss'].append(average_loss)
        training_log['train_acc'].append(average_accuracy)
        training_log['val_loss'].append(average_loss_val)
        training_log['val_acc'].append(average_accuracy_val)

        torch.save(training_log, os.path.join(args.save, 'training_log'))
        save_model(model, 'model', args.save)

        if epoch % 1 == 0:
            save_model(model, 'model', args.save)

        time_b = datetime.datetime.now()
        print('ETA:{}s/{}s'.format(
            (time_b - time_a).seconds,
            (time_b - time_a).seconds * (args.epoch - epoch)))
Beispiel #4
0
    train_loss_total = 0

    for data, target in train_loader:
        data, target = data.to(device), target.float().to(device)
        optimizer.zero_grad()
        output = model_pytorch(data)
        train_loss = criterion(output, target)
        train_loss.backward()
        optimizer.step()
        train_loss_total += train_loss.item() * data.size(0)

    print('Epoch {} completed. Train loss is {:.3f}'.format(epoch + 1, train_loss_total / train_size))
print('Time taken to completed {} epochs: {:.2f} minutes'.format(num_epochs, (time.time() - time_start) / 60))

# Evaluate model
model_pytorch.eval()

test_loss_total = 0
total_num_corrects = 0
threshold = 0.5
time_start = time.time()

for data, target in test_loader:
    data, target = data.to(device), target.float().to(device)
    optimizer.zero_grad()
    output = model_pytorch(data)
    train_loss = criterion(output, target)
    train_loss.backward()
    optimizer.step()
    train_loss_total += train_loss.item() * data.size(0)