예제 #1
0
        eval_loss += loss.item()
        # 记录准确率
        _, pred = out.max(1)
        num_correct = (pred == label).sum().item()
        acc = num_correct / img.shape[0]
        eval_acc += acc

    eval_losses.append(eval_loss / len(test_loader))
    eval_acces.append(eval_acc / len(test_loader))
    print(
        'epoch: {}, Train Loss: {:.4f}, Train Acc: {:.4f}, Test Loss: {:.4f}, Test Acc: {:.4f}'
        .format(epoch, train_loss / len(train_loader),
                train_acc / len(train_loader), eval_loss / len(test_loader),
                eval_acc / len(test_loader)))
# 将model保存为graph
torch.save(model.state_dict(), '../models/mixed_all_canshu_simplenet.pkl')
torch.save(model,
           '../models/mixed_all_model_simplenet.pkl')  # 保存整个神经网络的结构和模型参数


def draw_train_val(epochs, train_loss, val_loss, train_acc, val_acc):
    plt.subplot(2, 1, 1)
    plt.xlabel("epoch", fontsize=14)
    plt.ylabel("loss", fontsize=14)
    plt.plot(epochs, train_loss, color='red', label='training loss')
    plt.plot(epochs, val_loss, color='blue', label='validation loss')
    plt.legend(loc='best')
    plt.grid()

    plt.subplot(2, 1, 2)
    plt.xlabel("epoch", fontsize=14)
class Trainer:
    def __init__(self, device, trainData, validData, hidden_size, lr,
                 batch_size, arch):
        self.device = device
        self.trainData = trainData
        self.validData = validData
        self.model = SimpleNet(hidden_size).to(device)
        self.generator = Generator(hidden_size).to(device)
        self.discriminator = Discriminator(hidden_size).to(device)
        self.opt = torch.optim.Adam(self.model.parameters(), lr=1e-3)
        self.opt_G = torch.optim.Adam(self.generator.parameters(), lr=1e-4)
        self.opt_D = torch.optim.Adam(self.discriminator.parameters(), lr=1e-4)
        self.criterion = torch.nn.BCEWithLogitsLoss()
        self.scheduler = StepLR(self.opt, step_size=150, gamma=0.5)
        self.scheduler_G = StepLR(self.opt_G, step_size=300, gamma=0.5)
        self.scheduler_D = StepLR(self.opt_D, step_size=300, gamma=0.5)
        self.batch_size = batch_size
        self.arch = arch
        self.history = {'train': [], 'valid': []}

    def run_epoch(self, epoch, training):
        self.model.train(training)
        self.generator.train(training)
        self.discriminator.train(training)

        if training:
            description = 'Train'
            dataset = self.trainData
            shuffle = True
        else:
            description = 'Valid'
            dataset = self.validData
            shuffle = False
        dataloader = DataLoader(dataset=dataset,
                                batch_size=self.batch_size,
                                shuffle=shuffle,
                                collate_fn=dataset.collate_fn,
                                num_workers=4)

        trange = tqdm(enumerate(dataloader),
                      total=len(dataloader),
                      desc=description,
                      ascii=True)

        g_loss = 0
        d_loss = 0
        loss = 0
        accuracy = Accuracy()

        for i, (features, real_missing, labels) in trange:

            features = features.to(self.device)  # (batch, 11)
            real_missing = real_missing.to(self.device)  # (batch, 3)
            labels = labels.to(self.device)  # (batch, 1)
            batch_size = features.shape[0]

            if training:
                rand = torch.rand((batch_size, 11)).to(self.device) - 0.5
                std = features.std(dim=1)
                noise = rand * std.unsqueeze(1)
                features += noise

            # Adversarial ground truths
            valid = torch.FloatTensor(batch_size, 1).fill_(1.0).to(
                self.device)  # (batch, 1)
            fake = torch.FloatTensor(batch_size, 1).fill_(0.0).to(
                self.device)  # (batch, 1)

            # ---------------------
            #  Train Discriminator
            # ---------------------

            if i % 10 < 5 or not training:
                real_pred = self.discriminator(real_missing)
                d_real_loss = self.criterion(real_pred, valid)

                fake_missing = self.generator(features.detach())
                fake_pred = self.discriminator(fake_missing)
                d_fake_loss = self.criterion(fake_pred, fake)
                batch_d_loss = (d_real_loss + d_fake_loss)

                if training:
                    self.opt_D.zero_grad()
                    batch_d_loss.backward()
                    self.opt_D.step()
                d_loss += batch_d_loss.item()

            # -----------------
            #  Train Generator
            # -----------------

            if i % 10 >= 5 or not training:
                gen_missing = self.generator(features.detach())
                validity = self.discriminator(gen_missing)
                batch_g_loss = self.criterion(validity, valid)

                if training:
                    self.opt_G.zero_grad()
                    batch_g_loss.backward()
                    self.opt_G.step()
                g_loss += batch_g_loss.item()

                # ------------------
                #  Train Classifier
                # ------------------

                gen_missing = self.generator(features.detach())
                all_features = torch.cat((features, gen_missing), dim=1)
                o_labels = self.model(all_features)
                batch_loss = self.criterion(o_labels, labels)

                if training:
                    self.opt.zero_grad()
                    batch_loss.backward()
                    self.opt.step()
                loss += batch_loss.item()
                accuracy.update(o_labels, labels)

                trange.set_postfix(accuracy=accuracy.print_score(),
                                   g_loss=g_loss / (i + 1),
                                   d_loss=d_loss / (i + 1),
                                   loss=loss / (i + 1))

        if training:
            self.history['train'].append({
                'accuracy': accuracy.get_score(),
                'g_loss': g_loss / len(trange),
                'd_loss': d_loss / len(trange),
                'loss': loss / len(trange)
            })
            self.scheduler.step()
            self.scheduler_G.step()
            self.scheduler_D.step()
        else:
            self.history['valid'].append({
                'accuracy': accuracy.get_score(),
                'g_loss': g_loss / len(trange),
                'd_loss': d_loss / len(trange),
                'loss': loss / len(trange)
            })

    def save(self, epoch):
        if not os.path.exists(self.arch):
            os.makedirs(self.arch)

        path = self.arch + '/model.pkl.' + str(epoch)
        torch.save(
            {
                'model': self.model.state_dict(),
                'generator': self.generator.state_dict(),
                'discriminator': self.discriminator.state_dict()
            }, path)
        with open(self.arch + '/history.json', 'w') as f:
            json.dump(self.history, f, indent=4)
예제 #3
0
        1: [init_test_accuracy_per_class[1]]
    }

    # Test loss per class
    cur_loss = utils.get_loss_per_class(
        model, torch.nn.CrossEntropyLoss(reduction="sum"), test_loader,
        args.device, 2)
    test_loss_per_class = {0: [cur_loss[0]], 1: [cur_loss[1]]}

    cur_train_loss = utils.get_loss_per_class(
        model, torch.nn.CrossEntropyLoss(reduction="sum"), train_loader,
        args.device, 2)
    train_loss0 = [cur_train_loss[0]]
    train_loss1 = [cur_train_loss[1]]

    torch.save(model.state_dict(), args.save + "/model_params_init")

    for epoch in range(args.num_epoch):  # loop over the dataset multiple times
        model.train()
        running_loss1 = 0.0
        running_loss0 = 0.0
        for i, data in enumerate(train_loader, 0):
            # get the inputs
            inputs, labels = data

            # zero the parameter gradients
            optimizer.zero_grad()

            idx0 = labels == 0
            idx1 = labels == 1