示例#1
0
def test(model,
         test_generator,
         total_size,
         loss,
         input_channels,
         confusion_matrix=None,
         conv=True,
         one_trace=False,
         verbose=False,
         elec=False,
         output_size=2,
         exo=False,
         three_convs=False,
         clf=[]):
    '''
    Function to compute results in test set given a model.
    @model: model to use
    '''
    total_loss = []
    correct = 0
    total = 0
    cm = meter.ConfusionMeter(output_size)
    with torch.no_grad():
        for values in tqdm(test_generator):
            if (conv and one_trace and not three_convs):
                if (elec):

                    inp = Variable(values[0]).view(values[0].size(0), 1,
                                                   values[0].size(1),
                                                   values[0].size(2))

                    # inp = Variable(values[0]).view(values[0].size(0), 1, values[0].size(1))
                    inp = inp.cuda()
                else:
                    inp = Variable(values[0]).view(values[0].size(0), 1,
                                                   values[0].size(1))
            elif (conv and not three_convs):
                inp = Variable(values[0]).view(values[0].size(0),
                                               values[0].size(1),
                                               values[0].size(2))
                inp = inp.cuda()
            elif (conv and three_convs):
                inp_tank1 = Variable(values[0]).view(values[0].size(0), 1,
                                                     values[0].size(1),
                                                     values[0].size(2))
                inp_tank2 = Variable(values[1]).view(values[1].size(0), 1,
                                                     values[0].size(1),
                                                     values[1].size(2))
                inp_tank3 = Variable(values[2]).view(values[2].size(0), 1,
                                                     values[0].size(1),
                                                     values[2].size(2))
                inp_tank1 = inp_tank1.cuda()
                inp_tank2 = inp_tank2.cuda()
                inp_tank3 = inp_tank3.cuda()
            else:
                inp = Variable(values[0])
            if (exo):
                if (one_trace):
                    inp_exo = Variable(values[1]).view(values[1].size(0),
                                                       values[1].size(1))
                    output = Variable(values[2].squeeze()).type(
                        torch.LongTensor)
                    inp_exo = inp_exo.cuda()
                    output = output.cuda()
                else:
                    if (not three_convs):
                        inp_exo = Variable(values[1]).view(
                            values[1].size(0), values[1].size(1))
                        output = Variable(values[2].squeeze()).type(
                            torch.LongTensor)
                        inp_exo = inp_exo.cuda()
                        output = output.cuda()
                    else:
                        inp_exo = []
                        for value in values[3]:
                            aux = Variable(value).view(value.size(0),
                                                       value.size(1))
                            aux = aux.cuda()
                            inp_exo.append(aux)
                        output = Variable(values[4].squeeze()).type(
                            torch.LongTensor)
                        output = output.cuda()
            else:
                if (not three_convs):
                    output = Variable(values[1].squeeze()).type(
                        torch.LongTensor)
                    output = output.cuda()
                else:
                    output = Variable(values[3].squeeze()).type(
                        torch.LongTensor)
                    output = output.cuda()

            if (clf != []):
                usesvm = True
            else:
                usesvm = False

            if (exo):
                if (not three_convs):
                    predicted = model(inp, inp_exo)
                else:
                    predicted = model(inp_tank1, inp_tank2, inp_tank3, inp_exo,
                                      usesvm)
            elif (not three_convs):
                if (usesvm):
                    predicted = model(inp)
                else:
                    predicted = model(inp, usesvm)
            else:
                predicted = model(inp_tank1, inp_tank2, inp_tank3, svm_=usesvm)

            if (clf != []):
                predicted_cpu = predicted.cpu().detach().numpy()
                output_cpu = output.cpu().detach().numpy()
                predicted = clf.predict(predicted_cpu)
                if (cm is not None):
                    try:
                        cm.add(
                            torch.tensor(predicted).data.squeeze(),
                            output.type(torch.LongTensor))
                    except:
                        cm.add(predicted.data,
                               output.unsqueeze(0).type(torch.LongTensor))
                # softmax to get the probability of the classes
                # predicted = F.softmax(predicted, dim=1)
                try:
                    # total_loss.append(loss(predicted, output))
                    computed_loss = np.abs(predicted - output_cpu)
                    computed_loss = np.asarray(
                        np.sum(computed_loss) / computed_loss.shape[0])
                    total_loss.append(computed_loss)
                except:
                    total_loss.append(loss(predicted, output.unsqueeze(0)))
                try:
                    total += output.size(0)
                except:
                    total += 1
                # correct += (labels == output).sum().item()
                correct += (predicted == output_cpu).sum().item()
            else:
                _, labels = torch.max(predicted.data, 1)
                if (cm is not None):
                    try:
                        cm.add(predicted.data.squeeze(),
                               output.type(torch.LongTensor))
                    except:
                        cm.add(predicted.data,
                               output.unsqueeze(0).type(torch.LongTensor))
                try:
                    total_loss.append(loss(predicted, output))
                except:
                    total_loss.append(loss(predicted, output.unsqueeze(0)))
                try:
                    total += output.size(0)
                except:
                    total += 1
                correct += (labels == output).sum().item()
    if (verbose):
        print(
            'Mean and standard deviation in dataset with size {} are: {} +- {}'
            .format(total_size, np.mean(total_loss), np.std(total_loss)))
    try:
        return np.mean(total_loss), (100 * correct) / total, cm
    except:
        return torch.mean(torch.stack(total_loss),
                          dim=0), (100 * correct) / total, cm
示例#2
0
def train(model, training_generator, n_epochs, total_size, loss, optimizer,
          val_generator, val_size, conv, one_trace, verbose, elec, output_size,
          exo, three_convs, input_channels, usesvm):
    # Loss and optimizer
    best_model = model
    i = 0
    validation_losses = []
    training_losses = []
    validation_accuracy = []
    training_accuracy = []
    cms = []
    clf = []
    for epoch in range(n_epochs):
        print("Epoch {}/{}".format(epoch, n_epochs))
        batch_loss = []
        correct = 0
        total = 0
        stop = 0
        for values in tqdm(training_generator):
            if (conv and one_trace and not three_convs):
                if (elec):
                    inp = Variable(values[0]).view(values[0].size(0), 1,
                                                   values[0].size(1),
                                                   values[0].size(2))
                    # inp = Variable(values[0]).view(values[0].size(0), 1, values[0].size(1))
                    inp = inp.cuda()
                else:
                    inp = Variable(values[0]).view(values[0].size(0), 1,
                                                   values[0].size(1))
            elif (conv and not three_convs):
                inp = Variable(values[0]).view(values[0].size(0),
                                               values[0].size(1),
                                               values[0].size(2))
                inp = inp.cuda()
            elif (conv and three_convs):
                inp_tank1 = Variable(values[0]).view(values[0].size(0), 1,
                                                     values[0].size(1),
                                                     values[0].size(2))
                inp_tank2 = Variable(values[1]).view(values[1].size(0), 1,
                                                     values[0].size(1),
                                                     values[1].size(2))
                inp_tank3 = Variable(values[2]).view(values[2].size(0), 1,
                                                     values[0].size(1),
                                                     values[2].size(2))
                inp_tank1 = inp_tank1.cuda()
                inp_tank2 = inp_tank2.cuda()
                inp_tank3 = inp_tank3.cuda()
            else:
                inp = Variable(values[0])

            if (exo):
                if (not three_convs):
                    inp_exo = Variable(values[1]).view(values[1].size(0),
                                                       values[1].size(1))
                    output = Variable(values[2].squeeze()).type(
                        torch.LongTensor)
                    inp_exo = inp_exo.cuda()
                    output = output.cuda()
                else:
                    inp_exo = []
                    for value in values[3]:
                        aux = Variable(value).view(value.size(0),
                                                   value.size(1))
                        aux = aux.cuda()
                        inp_exo.append(aux)
                    output = Variable(values[4].squeeze()).type(
                        torch.LongTensor)
                    output = output.cuda()
            else:
                if (not three_convs):
                    output = Variable(values[1].squeeze()).type(
                        torch.LongTensor)
                    output = output.cuda()
                else:
                    output = Variable(values[3].squeeze()).type(
                        torch.LongTensor)
                    output = output.cuda()

            # Forward pass
            if (exo):
                if (not three_convs):
                    predicted = model(inp, inp_exo)
                else:
                    predicted = model(inp_tank1, inp_tank2, inp_tank3, inp_exo,
                                      usesvm)
            elif (not three_convs):
                if (usesvm):
                    predicted = model(inp)
                else:
                    predicted = model(inp, usesvm)
            else:
                predicted = model(inp_tank1, inp_tank2, inp_tank3, svm_=usesvm)

            if (usesvm):
                predicted_cpu = predicted.cpu().detach().numpy()
                output_cpu = output.cpu().detach().numpy()

                if (np.unique(output_cpu).shape[0] > 1):
                    svm_ = svm.SVC(kernel='rbf', gamma='scale')
                    if (not one_trace):
                        clf = GridSearchCV(svm_, parameters, cv=5)
                    else:
                        clf = svm_
                    clf.fit(predicted_cpu, output_cpu)
                    predicted = clf.predict(predicted_cpu)
                    # softmax to get the probability of the classes
                    # predicted = F.softmax(predicted, dim=1)
                    # _, labels = torch.max(predicted.data, 1)

                    try:
                        total += output.size(0)
                    except:
                        total += 1
                    correct += (predicted == output_cpu).sum().item()
                    # correct += (labels == output).sum().item()
                    try:
                        computed_loss = np.abs(predicted - output_cpu)
                        computed_loss = np.asarray(
                            np.sum(computed_loss) / computed_loss.shape[0])
                        computed_loss = torch.tensor(computed_loss,
                                                     requires_grad=True)
                        # computed_loss = loss(predicted, output)
                    except:
                        computed_loss = loss(predicted, output.unsqueeze(0))
                    batch_loss.append(computed_loss.item())
            else:
                # softmax to get the probability of the classes
                # predicted = F.softmax(predicted, dim=1)
                _, labels = torch.max(predicted.data, 1)
                try:
                    total += output.size(0)
                except:
                    total += 1
                correct += (labels == output).sum().item()
                try:
                    computed_loss = loss(predicted, output)
                except:
                    computed_loss = loss(predicted, output.unsqueeze(0))

                batch_loss.append(computed_loss.item())
                # Backward and optimize
                optimizer.zero_grad()
                computed_loss.backward()
                optimizer.step()
                stop += 1

        training_losses.append(np.mean(batch_loss))

        model = model.eval()
        i += 1
        confusion_matrix = meter.ConfusionMeter(
            output_size)  # I have 5 classes here
        val_loss, accuracy, confusion_matrix = validation(
            model,
            val_generator,
            val_size,
            loss,
            confusion_matrix=confusion_matrix,
            conv=conv,
            one_trace=one_trace,
            verbose=verbose,
            elec=elec,
            exo=exo,
            three_convs=three_convs,
            input_channels=input_channels,
            clf=clf)
        model = model.train()
        validation_losses.append(val_loss)
        print('Training: Epoch [{}/{}], Loss: {:.4f}, Acc: {:.4f}'.format(
            epoch + 1, n_epochs, computed_loss.item(),
            (100 * correct) / total))
        print('Val: Epoch [{}/{}], Loss: {:.4f}, Acc: {:.4f}'.format(
            epoch + 1, n_epochs, val_loss, accuracy))

        validation_accuracy.append(accuracy)
        cms.append(confusion_matrix)
        training_accuracy.append((100 * correct) / total)

    results = {
        "validation_losses": validation_losses,
        "training_losses": training_losses,
        "validation_accuracy": validation_accuracy,
        "training_accuracy": training_accuracy,
        "confusion_matrix": cms
    }
    return model.eval(), clf, results