Пример #1
0
def train(model_name, model_number, is_train, pretrained):
    BATCH_SIZE = 100
    LR = 0.001
    NUM_EPOCHS = 20

    # load model and dataset
    IMG_EXT = ".JPEG"
    TRAIN_IMG_PATH = "../data/train/images/"
    MODEL_PATH = "../model/" + model_name + model_number + "_1_model.pkl"
    LOSS_PATH = "../figure/" + model_name + model_number + "_1_loss.csv"
    LOSS_FIG_PATH = "../figure/" + model_name + model_number + "_1_loss.jpg"
    LOSS_FIG_TITLE = "CNN" + model_name + model_number + " loss"

    if model_name == "vgg":
        model = make_vgg(model_number)
    elif model_name == "resnet":
        model = make_resnet(model_number)
    else:
        print('choose valid model among vgg and resnet')

    if int(pretrained):
        print('load pretrained model')
        model.load_state_dict(torch.load(MODEL_PATH))

    if int(is_train):
        print('Train model only with 40,000 images.')
        TRAIN_DATA = "../data/train/train.csv"
    else:
        print('Train model with 50,000 images.')
        model.load_state_dict(torch.load(MODEL_PATH))
        TRAIN_DATA = "../data/train/validation.csv"

    # check whether use cuda or not
    is_cuda = torch.cuda.is_available()
    if is_cuda:
        model.cuda()

    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])

    transformations = transforms.Compose([
        transforms.Scale(64),
        transforms.RandomCrop(56),
        transforms.RandomHorizontalFlip(),
        transforms.ToTensor(), normalize
    ])

    kwargs = {'num_workers': 1, 'pin_memory': True} if is_cuda else {}
    train_dataset = TrainDataset(TRAIN_DATA, TRAIN_IMG_PATH, IMG_EXT,
                                 transformations)
    train_loader = DataLoader(train_dataset,
                              batch_size=BATCH_SIZE,
                              shuffle=True,
                              **kwargs)

    # Loss and Optimizer
    criterion = torch.nn.CrossEntropyLoss()
    optimizer = torch.optim.Adam(model.parameters(), lr=LR)

    # Train the Model
    print('Start training')
    model.train()
    losses = []
    for epoch in range(NUM_EPOCHS):
        for i, (images, labels) in enumerate(train_loader):
            if is_cuda:
                images = images.cuda()
                labels = labels.cuda()

            images = Variable(images)
            labels = Variable(labels)

            # Forward + Backward + Optimize
            optimizer.zero_grad()
            outputs = model(images)

            labels = labels.view(-1)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            if (i + 1) % 10 == 0:
                losses.append(loss.data[0])
                print('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f' %
                      (epoch + 1, NUM_EPOCHS, i + 1,
                       len(train_dataset) // BATCH_SIZE, loss.data[0]))

    print('Save model')
    torch.save(model.state_dict(), MODEL_PATH)
    save_fig(losses, LOSS_FIG_PATH, LOSS_FIG_TITLE)

    if not int(pretrained):
        with open(LOSS_PATH, 'w') as myfile:
            wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
            wr.writerow(losses)
Пример #2
0
def test(model_name, model_number, is_ensemble):
    is_ensemble = int(is_ensemble)
    BATCH_SIZE = 100

    # dataset and model path
    IMG_EXT = ".JPEG"
    TEST_IMG_PATH = "../data/test/images/"
    TEST_DATA = "../data/test/test_sample_submission_kaggle.csv"
    MODEL_PATH1 = "../model/" + model_name + model_number + "_test_1.pkl"
    MODEL_PATH2 = "../model/" + model_name + model_number + "_test_2.pkl"

    if is_ensemble:
        OUTPUT_PATH = "../result/" + model_name + model_number + "_ensemble_result.csv"
    else:
        OUTPUT_PATH = "../result/" + model_name + model_number + "_result.csv"

    is_cuda = torch.cuda.is_available()

    # data augmentation
    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])

    # resnet 18 and 34 get 224 * 224 image as input image
    if model_name == 'resnet' and (model_number == '18'
                                   or model_number == '34'):
        transformations = transforms.Compose(
            [transforms.Scale(224),
             transforms.ToTensor(), normalize])
    # other models get 56 * 56 image as input
    else:
        transformations = transforms.Compose(
            [transforms.ToTensor(), normalize])

    kwargs = {'num_workers': 1, 'pin_memory': True} if is_cuda else {}

    test_dataset = TestDataset(TEST_DATA, TEST_IMG_PATH, IMG_EXT,
                               transformations)
    test_loader = DataLoader(test_dataset,
                             batch_size=BATCH_SIZE,
                             shuffle=False,
                             **kwargs)

    # choose model architecture
    if model_name == "vgg":
        model1 = make_vgg(model_number)
        model2 = make_vgg(model_number)
    elif model_name == "resnet":
        model1 = make_resnet(model_number)
        model2 = make_resnet(model_number)
    else:
        print('choose valid model among vgg and resnet')

    # load trained model
    if is_ensemble:
        model1.load_state_dict(torch.load(MODEL_PATH1))
        model2.load_state_dict(torch.load(MODEL_PATH2))
        if is_cuda:
            model1.cuda()
            model2.cuda()
        model1.eval()
        model2.eval()

    else:
        model1.load_state_dict(torch.load(MODEL_PATH1))
        if is_cuda:
            model1.cuda()
        model1.eval()

    # estimate the result
    print('Testing start')
    header = list()
    header.append('id')
    class_names = ['class_' + str(x).zfill(3) for x in range(100)]

    for i in range(len(class_names)):
        header.append(class_names[i])

    results = list()

    for i, (images, ids) in enumerate(test_loader):
        if is_cuda:
            images = images.cuda()
        images = Variable(images)
        outputs1 = model1(images)
        if is_ensemble:
            outputs2 = model2(images)

        for j in range(len(outputs1)):
            result = list()
            result.append(ids[j])

            probs1 = torch.max(outputs1[j])
            # ensemble process
            if is_ensemble:
                probs2 = torch.max(outputs2[j])

                if probs1.max() > probs2.max():
                    output = list(outputs1[j].data)
                else:
                    output = list(outputs2[j].data)
            else:
                output = outputs1[j].data

            # output is log softmax
            # it is changed into softmax by exponent
            for k in range(len(output)):
                result.append(2**output[k])
            results.append(result)

        if (i + 1) % 10 == 0:
            print('Iter [%d/%d]' % (i + 1, len(test_dataset) // BATCH_SIZE))

    # save result
    df = pd.DataFrame.from_records(results, columns=header)
    df.to_csv(OUTPUT_PATH, index=False)
Пример #3
0
def validate(model_name, model_number, is_ensemble):
    is_ensemble = int(is_ensemble)
    BATCH_SIZE = 100

    # dataset and model path
    IMG_EXT = ".JPEG"
    VAL_IMG_PATH = "../data/train/images/"
    VAL_DATA = "../data/train/validation.csv"
    MODEL_PATH1 = "../model/" + model_name + model_number + "_val_1.pkl"
    MODEL_PATH2 = "../model/" + model_name + model_number + "_val_2.pkl"
    ACC_PATH1 = "../figure/" + model_name + model_number + "_accuracy_1.csv"
    ACC_FIG_PATH1 = "../figure/" + model_name + model_number + "_accuracy_1.jpg"
    ACC_FIG_TITLE1 = model_name + model_number + "model 1 accuracy"
    ACC_PATH2 = "../figure/" + model_name + model_number + "_accuracy_2.csv"
    ACC_FIG_PATH2 = "../figure/" + model_name + model_number + "_accuracy_2.jpg"
    ACC_FIG_TITLE2 = model_name + model_number + "model 2 accuracy"
    ACC_PATH = "../figure/" + model_name + model_number + "_accuracy.csv"
    ACC_FIG_PATH = "../figure/" + model_name + model_number + "_accuracy.jpg"
    ACC_FIG_TITLE = model_name + model_number + "model accuracy"

    # choose model architecture
    if model_name == "vgg":
        model1 = make_vgg(model_number)
        model2 = make_vgg(model_number)
    elif model_name == "resnet":
        model1 = make_resnet(model_number)
        model2 = make_resnet(model_number)
    else:
        print('choose valid model among vgg and resnet')

    print('Validate model with 10,000 images.')

    # load trained model
    is_cuda = torch.cuda.is_available()
    if is_ensemble:
        model1.load_state_dict(torch.load(MODEL_PATH1))
        model2.load_state_dict(torch.load(MODEL_PATH2))
        if is_cuda:
            model1.cuda()
            model2.cuda()
        model1.eval()
        model2.eval()
    else:
        model1.load_state_dict(torch.load(MODEL_PATH1))
        if is_cuda:
            model1.cuda()
        model1.eval()

    # data augmentation
    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])

    # resnet 18 and 34 get 224 * 224 image as input image
    if model_name == 'resnet' and (model_number == '18'
                                   or model_number == '34'):
        transformations = transforms.Compose(
            [transforms.Scale(224),
             transforms.ToTensor(), normalize])
    # other models get 56 * 56 image as input
    else:
        transformations = transforms.Compose(
            [transforms.ToTensor(), normalize])
    kwargs = {'num_workers': 1, 'pin_memory': True} if is_cuda else {}

    val_dataset = TrainDataset(VAL_DATA, VAL_IMG_PATH, IMG_EXT,
                               transformations)
    val_loader = DataLoader(val_dataset,
                            batch_size=BATCH_SIZE,
                            shuffle=False,
                            **kwargs)

    # validate the Model
    print('Validation start')
    accuracies = []
    correct = 0
    total = 0
    if is_ensemble:
        accuracies1 = []
        accuracies2 = []
        correct1 = 0
        correct2 = 0

    for i, (images, labels) in enumerate(val_loader):
        if is_cuda:
            images = images.cuda()
            labels = labels.cuda()
        images = Variable(images)
        outputs1 = model1(images)
        probs1, predicted1 = torch.max(outputs1.data, 1)

        if is_ensemble:
            outputs2 = model2(images)
            probs2, predicted2 = torch.max(outputs2.data, 1)

            predicted = []
            # ensemble process
            # choose the highest probability among the model
            for j in range(len(probs1)):
                if probs1[j].max() > probs2[j].max():
                    prediction = predicted1[j].max()
                else:
                    prediction = predicted2[j].max()
                predicted.append(prediction)
            predicted = torch.LongTensor(predicted).cuda()

        total += labels.size(0)
        correct += (predicted1 == labels).sum()
        accuracies.append(100 * correct / float(total))

        if is_ensemble:
            correct1 += (predicted1 == labels).sum()
            correct2 += (predicted2 == labels).sum()
            accuracies1.append(100 * correct1 / float(total))
            accuracies2.append(100 * correct2 / float(total))

        if (i + 1) % 10 == 0:
            print(
                'Iter [%d/%d] Accuracy: %.4f' %
                (i + 1, len(val_dataset) // BATCH_SIZE, 100 * correct / total))

    print('Test Accuracy of the model on the %d test images: %d %%' %
          (len(val_dataset), 100 * correct / total))

    # save accuracy data
    save_fig(accuracies, ACC_FIG_PATH, ACC_FIG_TITLE)
    with open(ACC_PATH, 'w') as myfile:
        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
        wr.writerow(accuracies)

    if is_ensemble:
        save_fig(accuracies1, ACC_FIG_PATH1, ACC_FIG_TITLE1)
        save_fig(accuracies2, ACC_FIG_PATH2, ACC_FIG_TITLE2)

        with open(ACC_PATH1, 'w') as myfile:
            wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
            wr.writerow(accuracies1)
        with open(ACC_PATH2, 'w') as myfile:
            wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
            wr.writerow(accuracies2)
Пример #4
0
def train(model_name, model_number, model_index, is_validation):
    is_validation = int(is_validation)
    BATCH_SIZE = 100
    LR = 0.001
    NUM_EPOCHS = 1
    
    # dataset path
    IMG_EXT = ".JPEG"
    TRAIN_IMG_PATH = "../data/train/images/"

    # train 40,000 dataset for validation
    if is_validation:    
        MODEL_PATH = "../model/" + model_name + model_number + "_val_" + model_index + ".pkl"
        LOSS_PATH = "../figure/" + model_name + model_number + "_val_loss_" + model_index + ".csv"
        LOSS_FIG_PATH = "../figure/" + model_name + model_number + "_val_loss_" + model_index + ".jpg"
        LOSS_FIG_TITLE = "CNN" + model_name + model_number + " val loss"
        TRAIN_DATA = "../data/train/train.csv" 
        print('Train model with 40,000 images.')
        
    # train 50,000 dataset for test
    else:
        MODEL_PATH = "../model/" + model_name + model_number + "_test_" + model_index + ".pkl"
        LOSS_PATH = "../figure/" + model_name + model_number + "_test_loss_" + model_index + ".csv"
        LOSS_FIG_PATH = "../figure/" + model_name + model_number + "_test_loss_" + model_index + ".jpg"
        LOSS_FIG_TITLE = "CNN" + model_name + model_number + " test loss"
        print('Train model with 50,000 images.')
        TRAIN_DATA = "../data/train/train_labels.csv"          
 
    # choose model architecture
    if model_name == "vgg":
        model = make_vgg(model_number)
    elif model_name == "resnet":
        model = make_resnet(model_number)
    else:
        print('choose valid model among vgg and resnet')

   
    # check whether use cuda or not
    is_cuda = torch.cuda.is_available()
    if is_cuda:
        print('Learning with cuda')
        model.cuda()
    
    # data augmentation
    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])
    
    if model_name == 'resnet' and (model_number == '18' or model_number == '34'):
        transformations = transforms.Compose([
    								transforms.Scale(256),
    								transforms.RandomCrop(224),
                                    transforms.RandomHorizontalFlip(),
                                    transforms.ToTensor(),
                                    normalize])
    else:
        transformations = transforms.Compose([
    								transforms.Scale(64),
    								transforms.RandomCrop(56),
                                    transforms.RandomHorizontalFlip(),
                                    transforms.ToTensor(),
                                    normalize])        
    
    kwargs = {'num_workers':1, 'pin_memory':True} if is_cuda else {}
    train_dataset = TrainDataset(TRAIN_DATA, TRAIN_IMG_PATH, IMG_EXT, transformations)
    train_loader = DataLoader(train_dataset,
                              batch_size = BATCH_SIZE,
                              shuffle=True,
                              **kwargs)

    # loss and optimizer
    criterion = torch.nn.CrossEntropyLoss()
    optimizer = torch.optim.SGD(model.parameters(), lr=LR, momentum=0.9)

    # train the model    
    print('Start training')
    model.train()
    losses = []
    for epoch in range(NUM_EPOCHS):
        optimizer = exp_lr_scheduler(optimizer, epoch, LR, 4)        
        for i, (images, labels) in enumerate(train_loader):
            if is_cuda:
                images = images.cuda()
                labels = labels.cuda()
            
            images = Variable(images)
            labels = Variable(labels)
            
            # Forward + Backward + Optimize
            optimizer.zero_grad()
            outputs = model(images)
            
            labels = labels.view(-1)
            loss = criterion(outputs, labels)
            loss.backward()
            optimizer.step()
            if (i+1) % 10 == 0:
                losses.append(loss.data[0])
                print ('Epoch [%d/%d], Iter [%d/%d] Loss: %.4f' 
                       %(epoch+1, NUM_EPOCHS, i+1, len(train_dataset)//BATCH_SIZE, loss.data[0]))

    print('Save model')
    
    # save model and loss data
    torch.save(model.state_dict(), MODEL_PATH)    
    save_fig(losses, LOSS_FIG_PATH, LOSS_FIG_TITLE )
    
    with open(LOSS_PATH, 'w') as myfile:
        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
        wr.writerow(losses)
Пример #5
0
def validate(model_name, model_number):
    BATCH_SIZE = 100

    # load model and dataset

    IMG_EXT = ".JPEG"
    VAL_IMG_PATH = "../data/train/images/"
    VAL_DATA = "../data/train/validation.csv"
    MODEL_PATH = "../model/" + model_name + model_number + "_model_2.pkl"
    ACC_PATH = "../figure/" + model_name + model_number + "_accuracy.csv"
    ACC_FIG_PATH = "../figure/" + model_name + model_number + "_accuracy.jpg"
    ACC_FIG_TITLE = model_name + model_number + " accuracy"

    if model_name == "vgg":
        model = make_vgg(model_number)
    elif model_name == "resnet":
        model = make_resnet(model_number)
    else:
        print('choose valid model among vgg and resnet')

    print('Validate model with 10,000 images.')
    model.load_state_dict(torch.load(MODEL_PATH))

    # check whether use cuda or not
    is_cuda = torch.cuda.is_available()
    if is_cuda:
        model.cuda()

    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])

    if model_name == 'resnet' and (model_number == '18'
                                   or model_number == '34'):
        transformations = transforms.Compose(
            [transforms.Scale(224),
             transforms.ToTensor(), normalize])
    else:
        transformations = transforms.Compose(
            [transforms.ToTensor(), normalize])

    kwargs = {'num_workers': 1, 'pin_memory': True} if is_cuda else {}

    val_dataset = TrainDataset(VAL_DATA, VAL_IMG_PATH, IMG_EXT,
                               transformations)
    val_loader = DataLoader(val_dataset,
                            batch_size=BATCH_SIZE,
                            shuffle=False,
                            **kwargs)

    # validate the Model
    print('Validation start')
    accuracies = []
    model.eval()  # Change model to 'eval' mode (BN uses moving mean/var).
    correct = 0
    total = 0
    for i, (images, labels) in enumerate(val_loader):
        if is_cuda:
            images = images.cuda()
            labels = labels.cuda()
        images = Variable(images)
        outputs = model(images)

        _, predicted = torch.max(outputs.data, 1)
        total += labels.size(0)
        correct += (predicted == labels).sum()
        accuracies.append(100 * correct / float(total))

        if (i + 1) % 10 == 0:
            print(
                'Iter [%d/%d] Accuracy: %.4f' %
                (i + 1, len(val_dataset) // BATCH_SIZE, 100 * correct / total))

    print('Test Accuracy of the model on the %d test images: %d %%' %
          (len(val_dataset), 100 * correct / total))
    save_fig(accuracies, ACC_FIG_PATH, ACC_FIG_TITLE)
    with open(ACC_PATH, 'w') as myfile:
        wr = csv.writer(myfile, quoting=csv.QUOTE_ALL)
        wr.writerow(accuracies)
Пример #6
0
def test(model_name, model_number):
    BATCH_SIZE = 100
    IMG_EXT = ".JPEG"
    TEST_IMG_PATH = "../data/test/images/"
    TEST_DATA = "../data/test/test_sample_submission_kaggle.csv"
    MODEL_PATH = "../model/" + model_name + model_number + "_test_1.pkl"
    OUTPUT_PATH = "../result/" + model_name + model_number + "_result.csv"

    is_cuda = torch.cuda.is_available()

    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])
    transformations = transforms.Compose(
        [transforms.Scale(224),
         transforms.ToTensor(), normalize])

    kwargs = {'num_workers': 1, 'pin_memory': True} if is_cuda else {}
    test_dataset = TestDataset(TEST_DATA, TEST_IMG_PATH, IMG_EXT,
                               transformations)

    test_loader = DataLoader(test_dataset,
                             batch_size=BATCH_SIZE,
                             shuffle=False,
                             **kwargs)

    if model_name == "vgg":
        model = make_vgg(model_number)
    elif model_name == "resnet":
        model = make_resnet(model_number)
    else:
        print('choose valid model among vgg and resnet')

    model.load_state_dict(torch.load(MODEL_PATH))

    if is_cuda:
        model.cuda()

    model.eval()

    header = list()
    header.append('id')
    class_names = ['class_' + str(x).zfill(3) for x in range(100)]

    for i in range(len(class_names)):
        header.append(class_names[i])

    results = list()

    print('Testing start')
    for i, (images, ids) in enumerate(test_loader):
        if is_cuda:
            images = images.cuda()
        images = Variable(images)
        outputs = model(images)

        for j in range(len(outputs)):
            result = list()
            result.append(ids[j])
            output = list(outputs[j].data)
            for k in range(len(output)):
                result.append(2**output[k])  #log -> probability
                #result.append(round(output[k],2))
            results.append(result)

        if (i + 1) % 10 == 0:
            print('Iter [%d/%d]' % (i + 1, len(test_dataset) // BATCH_SIZE))

    df = pd.DataFrame.from_records(results, columns=header)
    df.to_csv(OUTPUT_PATH, index=False)