def train_lenet(split_dir):
    """训练lenet"""
    set_seed()  # 设置随机种子
    rmb_label = {"1": 0, "100": 1}

    # 参数设置
    MAX_EPOCH = 10
    BATCH_SIZE = 16
    LR = 0.01
    log_interval = 10
    val_interval = 1
    """Step 1: 数据读取"""
    train_dir = os.path.join(split_dir, "train")
    valid_dir = os.path.join(split_dir, "valid")
    test_dir = os.path.join(split_dir, "test")

    norm_mean = [0.485, 0.456, 0.406]
    norm_std = [0.229, 0.224, 0.225]

    # 对训练数据进行变换,添加RandomCrop进行数据增强
    train_transform = transforms.Compose([
        transforms.Resize((32, 32)),
        transforms.RandomCrop(32, padding=4),
        transforms.ToTensor(),
        transforms.Normalize(norm_mean, norm_std),
    ])

    # 对验证数据进行变换
    valid_transform = transforms.Compose([
        transforms.Resize((32, 32)),
        transforms.ToTensor(),
        transforms.Normalize(norm_mean, norm_std),
    ])

    # 构建RMBDataset实例
    train_data = RMBDataset(data_dir=train_dir, transform=train_transform)
    valid_data = RMBDataset(data_dir=valid_dir, transform=valid_transform)

    # 构建DataLoader
    train_loader = DataLoader(dataset=train_data,
                              batch_size=BATCH_SIZE,
                              shuffle=True)
    valid_loader = DataLoader(dataset=valid_data, batch_size=BATCH_SIZE)
    """Step 2: 模型"""
    net = LeNet(classes=2)
    net.initialize_weights()
    """Step 3: 损失函数"""
    criterion = nn.CrossEntropyLoss()
    """Step 4: 优化器"""
    optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.9)
    scheduler = torch.optim.lr_scheduler.StepLR(optimizer,
                                                step_size=10,
                                                gamma=0.1)
    """Step 5: 训练"""
    train_curve = []
    valid_curve = []

    figure_dir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                              'result')

    for epoch in range(MAX_EPOCH):
        loss_mean = 0.
        correct = 0.
        total = 0.

        net.train()
        for i, data in enumerate(train_loader):

            # forward
            inputs, labels = data
            outputs = net(inputs)

            # backward
            optimizer.zero_grad()
            loss = criterion(outputs, labels)
            loss.backward()

            # update weights
            optimizer.step()

            # 统计分类情况
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).squeeze().sum().numpy()

            # 打印训练信息
            loss_mean += loss.item()
            train_curve.append(loss.item())
            if (i + 1) % log_interval == 0:
                loss_mean = loss_mean / log_interval
                print(
                    "Training:Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2%}"
                    .format(epoch, MAX_EPOCH, i + 1, len(train_loader),
                            loss_mean, correct / total))
                loss_mean = 0.

        scheduler.step()  # 更新学习率

        # validate the model
        if (epoch + 1) % val_interval == 0:

            correct_val = 0.
            total_val = 0.
            loss_val = 0.
            net.eval()
            with torch.no_grad():
                for j, data in enumerate(valid_loader):
                    inputs, labels = data
                    outputs = net(inputs)
                    loss = criterion(outputs, labels)

                    _, predicted = torch.max(outputs.data, 1)
                    total_val += labels.size(0)
                    correct_val += (
                        predicted == labels).squeeze().sum().numpy()

                    loss_val += loss.item()

                valid_curve.append(loss_val / valid_loader.__len__())
                print(
                    "Valid:\t Epoch[{:0>3}/{:0>3}] Iteration[{:0>3}/{:0>3}] Loss: {:.4f} Acc:{:.2%}"
                    .format(epoch, MAX_EPOCH, j + 1, len(valid_loader),
                            loss_val, correct_val / total_val))

    train_x = range(len(train_curve))
    train_y = train_curve

    train_iters = len(train_loader)
    valid_x = np.arange(
        1,
        len(valid_curve) + 1
    ) * train_iters * val_interval  # 由于valid中记录的是epochloss,需要对记录点进行转换到iterations
    valid_y = valid_curve

    plt.plot(train_x, train_y, label='Train')
    plt.plot(valid_x, valid_y, label='Valid')

    plt.legend(loc='upper right')
    plt.ylabel('loss value')
    plt.xlabel('Iteration')
    figure_path = os.path.join(figure_dir, '0201.png')
    plt.savefig(figure_path)
    plt.close()
# ============================ step 4/5 优化器 ============================
optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.9)  # 选择优化器
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10,
                                            gamma=0.1)  # 设置学习率下降策略

# ============================ step 5/5 训练 ============================
train_curve = list()
valid_curve = list()

for epoch in range(MAX_EPOCH):

    loss_mean = 0.
    correct = 0.
    total = 0.

    net.train()
    for i, data in enumerate(train_loader):

        # forward
        inputs, labels = data
        outputs = net(inputs)

        # backward
        optimizer.zero_grad()
        loss = criterion(outputs, labels)
        loss.backward()

        # update weights
        optimizer.step()

        # 统计分类情况
Exemple #3
0
import os
import random
import cv2
import numpy as np
from lenet import LeNet


def get_training_data(data_dir):
    images = []
    labels = []
    files = os.listdir(data_dir)
    random.shuffle(files)
    for f in files:
        img = cv2.imread(os.path.join(data_dir, f), cv2.IMREAD_GRAYSCALE)
        img = cv2.resize(img, (32, 32))
        img = img.astype(np.float32).reshape(32, 32, 1) / 255.0
        images.append(img)
        num = int(f[0])
        label = np.zeros(10, dtype=np.float32)
        label[num] = 1
        labels.append(label)
    return (np.array(images), np.array(labels))


if __name__ == '__main__':
    x, y = get_training_data("mnist/train")
    lenet = LeNet()
    lenet.train(x, y)
    lenet.save("lenet.npy")
                                              batch_size=args.batch_size,
                                              shuffle=True,
                                              pin_memory=cuda)

    testloader = torch.utils.data.DataLoader(testset,
                                             batch_size=args.batch_size,
                                             shuffle=False,
                                             pin_memory=cuda)

    model = LeNet(k=len(classes), args=args)

    if cuda:
        model.cuda()

    for epoch in range(1, args.epochs + 1):
        model.train()

        for i, (x_batch, y_batch) in enumerate(trainloader):
            if cuda:
                x_batch, y_batch = x_batch.cuda(), y_batch.cuda()

            model.optimizer.zero_grad()

            # forward + backward + optimize
            output = model(x_batch)
            loss = model.criterion(output, y_batch)
            loss.backward()
            model.optimizer.step()

            if i % args.log_interval == 0:
                print('Epoch: {:3d}, Batch {:3d}/{}, Loss: {:.5f}'.format(
Exemple #5
0
class Ui(QtWidgets.QMainWindow):
    buttons = [
       "load_image", "color_conversion", "image_flipping",
       "blending", "global_threshold", "local_threshold",
       "gaussian", "sobel_x", "sobel_y", "magnitude", "rst",
       "show_train_image", "show_hyper", "train_1", "pt",
       "inference", "ok", "show_train_result", "cancel"]
    inputs = ["angle", "scale", "tx", "ty", "test_index"]

    def __init__(self):
        super(Ui, self).__init__()

        uic.loadUi('main_window.ui', self)
        self.get_widgets()
        self.get_input()
        self.bind_event()
        self.param_setup()
        self.torch_setup()
        self.show()

    def get_widgets(self):
        for btn in self.buttons:
            setattr(self, btn, self.findChild(QtWidgets.QPushButton, btn))
    
    def get_input(self):
        for inp in self.inputs:
            setattr(self, inp, self.findChild(QtWidgets.QLineEdit, inp))


    def bind_event(self):
        for btn in self.buttons:
            getattr(self, btn).clicked.connect(partial(
                getattr(events,  btn), 
                self))
    def param_setup(self):
        self.batch_size = 32
        self.learning_rate = 0.001
        self.opt = "SGD"
        self.loss_list = []
        self.loss_epoch = []
        self.acc_train_epoch = []
        self.acc_test_epoch = []
        self.compose = transforms.Compose([
            transforms.Resize((32,32)),
            transforms.ToTensor()
        ])


    def torch_setup(self):
        self.data_train = MNIST('./data/mnist',
                            train=True,
                            download=True,
                            transform=self.compose)
                            
        self.data_test = MNIST('./data/mnist',
                            train=False,
                            download=True,
                            transform=self.compose)
        self.data_train_loader = DataLoader(self.data_train, batch_size=self.batch_size, shuffle=True, num_workers=4)
        self.data_test_loader = DataLoader(self.data_test, batch_size=self.batch_size, num_workers=4)
        self.criterion = nn.CrossEntropyLoss()
        self.net = LeNet()
        self.optimizer = getattr(optim, self.opt)(self.net.parameters(), lr=self.learning_rate)

        try:
            self.net.load_state_dict(load('model_params.pkl'))
            self.loaded = True
            print("Loaded")
        except Exception as e:
            print(e)
            self.loaded = False
            print("Not loaded")

    def train(self, epoch):
        self.net.train()
        self.loss_list = []
        correct, total = 0, 0
        for i, (images, labels) in enumerate(self.data_train_loader):
            self.optimizer.zero_grad()
            output = self.net(images)
            loss = self.criterion(output, labels)
            pred = output.data.max(1, keepdim=True)[1]
            correct += np.sum(np.squeeze(pred.eq(labels.data.view_as(pred))).cpu().numpy())
            total += images.size(0)
            self.loss_list.append(loss.detach().cpu().item())

            if i % 100 == 0:
                print(f'Train - Epoch {epoch}, Batch: {i}, Loss: {loss.detach().cpu().item()}')

            loss.backward()
            self.optimizer.step()
        self.acc_train_epoch.append(correct/total)
        self.loss_epoch.append(sum(self.loss_list)/len(self.loss_list))

    def test(self):
        self.net.eval()
        total_correct, avg_loss = 0, 0.0
        for i, (images, labels) in enumerate(self.data_test_loader):
            output = self.net(images)
            avg_loss += self.criterion(output, labels).sum()
            pred = output.detach().max(1)[1]
            total_correct += pred.eq(labels.view_as(pred)).sum()

        avg_loss /= len(self.data_test)
        acc = float(total_correct)/len(self.data_test)
        self.acc_test_epoch.append(acc)

    def test_and_train(self, epoch):
        self.train(epoch)
        self.test()
Exemple #6
0
def training(model_name, trainloader, validloader, input_channel=3, epochs=1, resume=True, self_define=True, only_print=False):
    # load self defined or official net
    assert model_name in ["LeNet", "VGG16", "ResNet", "DenseNet"]

    if self_define:
        if model_name == "LeNet":
            net = LeNet(input_channel)
        elif model_name == "VGG16":
            net = VGG16(input_channel)
        elif model_name == "ResNet":
            net = ResNet(input_channel)
        elif model_name == "DenseNet":
            net = DenseNet(input_channel)
    else:
        if model_name == "LeNet":
            net = LeNet(input_channel)  # on official LeNet
        elif model_name == "VGG16":
            net = models.vgg16_bn(pretrained=False, num_classes=10)
        elif model_name == "ResNet":
            net = models.resnet50(pretrained=False, num_classes=10)
        elif model_name == "DenseNet":
            net = models.DenseNet(num_classes=10)

    # sum of net parameters number
    print("Number of trainable parameters in %s : %f" % (model_name, sum(p.numel() for p in net.parameters() if p.requires_grad)))

    # print model structure
    if only_print:
        print(net)
        return

    # resume training
    param_path = "./model/%s_%s_parameter.pt" % (model_name, "define" if self_define else "official")
    if resume:
        if os.path.exists(param_path):
            net.load_state_dict(torch.load(param_path))
            net.train()
            print("Resume training " + model_name)
        else:
            print("Train %s from scratch" % model_name)
    else:
        print("Train %s from scratch" % model_name)

    # define loss function and optimizer
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.SGD(net.parameters(), lr=0.001, momentum=0.9)

    # train on GPU
    device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
    print('train on %s' % device)
    net.to(device)

    running_loss = 0.0
    train_losses = []
    valid_losses = []
    mini_batches = 125 * 5
    for epoch in range(epochs):
        for i, data in enumerate(trainloader, 0):
            # get one batch
            # inputs, labels = data
            inputs, labels = data[0].to(device), data[1].to(device)
    
            # switch model to training mode, clear gradient accumulators
            net.train()
            optimizer.zero_grad()
    
            # forward + backward + optimize
            outputs = net(inputs)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
    
            # print statistics
            running_loss += loss.item()
            if i % mini_batches == mini_batches - 1:  # print and valid every <mini_batches> mini-batches
                # validate model in validation dataset
                valid_loss = valid(net, validloader, criterion, device)
                print('[%d, %5d] train loss: %.3f,  validset loss: %.3f' % (
                    epoch + 1, i + 1, running_loss / mini_batches, valid_loss))
                train_losses.append(running_loss / mini_batches)
                valid_losses.append(valid_loss)
                running_loss = 0.0

        # save parameters
        torch.save(net.state_dict(), param_path)

        # # save checkpoint
        # torch.save({
        #     'epoch': epoch,
        #     'model_state_dict': net.state_dict(),
        #     'optimizer_state_dict': optimizer.state_dict(),
        #     'loss': loss
        # }, "./checkpoints/epoch_" + str(epoch) + ".tar")
    
    print('Finished Training, %d images in all' % (len(train_losses) * batch_size * mini_batches / epochs))
    
    # draw loss curve
    assert len(train_losses) == len(valid_losses)
    loss_x = range(0, len(train_losses))
    plt.plot(loss_x, train_losses, label="train loss")
    plt.plot(loss_x, valid_losses, label="valid loss")
    plt.title("Loss for every %d mini-batch" % mini_batches)
    plt.xlabel("%d mini-batches" % mini_batches)
    plt.ylabel("Loss")
    plt.legend()
    plt.savefig(model_name + "_loss.png")
    plt.show()
Exemple #7
0
    train_generator = Datagenerator(file, 'train', num, batch_size)
    test_generator = Datagenerator(file, 'test', num, 200)

    #define and initialize LeNet-5
    net = LeNet(rbf_w)
    net.init_weights()

    step = 0

    for eps in range(epochs):
        train_generator.get_data('batch', True)
        while True:
            try:
                train_images, train_labels = train_generator.gen_batch()

                train_loss, train_acc = net.train(train_images, train_labels)

                if step % 10 == 0:
                    record_loss.append(train_loss)
                    record_acc.append(train_acc)
                    print('step --> %d, loss : %.4f, acc : %.2f' %
                          (step, train_loss, train_acc))

                step += 1
            except OutOfRange:
                # finish a epoch, validate test set
                test_generator.get_data('batch', False)
                tacc = []
                while True:
                    try:
                        test_images, test_labels = test_generator.gen_batch()