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)
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)
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)
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)
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)
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)