def download(nnArchitecture, nnIsTrained, nnClassCount): #-------------------- SETTINGS: NETWORK ARCHITECTURE if nnArchitecture == 'DENSE-NET-121': model = DenseNet121(nnClassCount, nnIsTrained) elif nnArchitecture == 'DENSE-NET-169': model = DenseNet169(nnClassCount, nnIsTrained) elif nnArchitecture == 'DENSE-NET-201': model = DenseNet201(nnClassCount, nnIsTrained) elif nnArchitecture == 'RES-NET-18': model = ResNet18(nnClassCount, nnIsTrained) elif nnArchitecture == 'RES-NET-50': model = ResNet50(nnClassCount, nnIsTrained) model = torch.nn.DataParallel(model)
def test (pathDirData, pathFileTest, pathModel, nnArchitecture, nnClassCount, nnIsTrained, trBatchSize, transResize, transCrop, launchTimeStamp): CLASS_NAMES = [ 'Atelectasis', 'Cardiomegaly', 'Effusion', 'Infiltration', 'Mass', 'Nodule', 'Pneumonia', 'Pneumothorax', 'Consolidation', 'Edema', 'Emphysema', 'Fibrosis', 'Pleural_Thickening', 'Hernia'] cudnn.benchmark = True #-------------------- SETTINGS: NETWORK ARCHITECTURE, MODEL LOAD if nnArchitecture == 'DENSE-NET-121': model = DenseNet121(nnClassCount, nnIsTrained).cuda() elif nnArchitecture == 'DENSE-NET-169': model = DenseNet169(nnClassCount, nnIsTrained).cuda() elif nnArchitecture == 'DENSE-NET-201': model = DenseNet201(nnClassCount, nnIsTrained).cuda() elif nnArchitecture == 'RES-NET-18': model = ResNet18(nnClassCount, nnIsTrained).cuda() elif nnArchitecture == 'RES-NET-50': model = ResNet50(nnClassCount, nnIsTrained).cuda() model = torch.nn.DataParallel(model).cuda() modelCheckpoint = torch.load(os.path.join("models", pathModel)) model.load_state_dict(modelCheckpoint['state_dict']) #-------------------- SETTINGS: DATA TRANSFORMS, TEN CROPS normalize = transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) #-------------------- SETTINGS: DATASET BUILDERS transformList = [] # transformList.append(transforms.Resize(transResize)) transformList.append(transforms.TenCrop(transCrop)) transformList.append(transforms.Lambda(lambda crops: torch.stack([transforms.ToTensor()(crop) for crop in crops]))) transformList.append(transforms.Lambda(lambda crops: torch.stack([normalize(crop) for crop in crops]))) transformSequence=transforms.Compose(transformList) datasetTest = DatasetGenerator(pathImageDirectory=pathDirData, pathDatasetFile=pathFileTest, transform=transformSequence) dataLoaderTest = DataLoader(dataset=datasetTest, batch_size=trBatchSize, num_workers=8, shuffle=False, pin_memory=True) # outGT = torch.FloatTensor().cuda() # outPRED = torch.FloatTensor().cuda() outGT = [] outPRED = [] model.eval() for i, (input, target) in enumerate(dataLoaderTest): # outGT = torch.cat((outGT, target), 0) outGT.append(target.numpy()) bs, n_crops, c, h, w = input.size() out = model(input.view(-1, c, h, w).cuda()) outMean = out.detach().cpu().numpy().reshape(bs, n_crops, -1).mean(axis=1) # outPRED = torch.cat((outPRED, outMean.data), 0) outPRED.append(outMean) del out outGT = np.concatenate(outGT, axis=0) outPRED = np.concatenate(outPRED, axis=0) aurocIndividual = ChexnetTrainer.computeAUROC(outGT, outPRED, nnClassCount) aurocMean = np.array(aurocIndividual).mean() modelTested = pathModel.split("/")[-1].replace(".pth.tar", "") modelResultsPath = os.path.join("results", modelTested + ".txt") with open(modelResultsPath, "w") as f: print ('Architecture: ', nnArchitecture, file=f) print ('AUROC mean ', aurocMean, file=f) for i in range (0, len(aurocIndividual)): print (CLASS_NAMES[i], ' ', aurocIndividual[i], file=f) print ('Architecture: ', nnArchitecture) print ('AUROC mean ', aurocMean) for i in range (0, len(aurocIndividual)): print (CLASS_NAMES[i], ' ', aurocIndividual[i]) return
def train (pathDirData, pathFileTrain, pathFileVal, nnArchitecture, nnIsTrained, nnClassCount, trBatchSize, trMaxEpoch, transResize, transCrop, launchTimestamp, checkpoint): #-------------------- SETTINGS: NETWORK ARCHITECTURE if nnArchitecture == 'DENSE-NET-121': model = DenseNet121(nnClassCount, nnIsTrained).cuda() elif nnArchitecture == 'DENSE-NET-169': model = DenseNet169(nnClassCount, nnIsTrained).cuda() elif nnArchitecture == 'DENSE-NET-201': model = DenseNet201(nnClassCount, nnIsTrained).cuda() elif nnArchitecture == 'RES-NET-18': model = ResNet18(nnClassCount, nnIsTrained).cuda() elif nnArchitecture == 'RES-NET-50': model = ResNet50(nnClassCount, nnIsTrained).cuda() model = torch.nn.DataParallel(model).cuda() #-------------------- SETTINGS: DATA TRANSFORMS normalize = transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) transformList = [] transformList.append(transforms.RandomResizedCrop(transCrop)) transformList.append(transforms.RandomHorizontalFlip()) transformList.append(transforms.ToTensor()) transformList.append(normalize) transformSequence=transforms.Compose(transformList) #-------------------- SETTINGS: DATASET BUILDERS datasetTrain = DatasetGenerator(pathImageDirectory=pathDirData, pathDatasetFile=pathFileTrain, transform=transformSequence) datasetVal = DatasetGenerator(pathImageDirectory=pathDirData, pathDatasetFile=pathFileVal, transform=transformSequence) dataLoaderTrain = DataLoader(dataset=datasetTrain, batch_size=trBatchSize, shuffle=True, num_workers=24, pin_memory=True) dataLoaderVal = DataLoader(dataset=datasetVal, batch_size=trBatchSize, shuffle=False, num_workers=24, pin_memory=True) #-------------------- SETTINGS: OPTIMIZER & SCHEDULER optimizer = optim.Adam (model.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=1e-5) scheduler = ReduceLROnPlateau(optimizer, factor = 0.1, patience = 5, mode = 'min') #-------------------- SETTINGS: LOSS loss = torch.nn.BCELoss(size_average = True) #---- Load checkpoint if checkpoint != None: modelCheckpoint = torch.load(checkpoint) model.load_state_dict(modelCheckpoint['state_dict']) optimizer.load_state_dict(modelCheckpoint['optimizer']) #---- TRAIN THE NETWORK lossMIN = 100000 for epochID in range (0, trMaxEpoch): timestampTime = time.strftime("%H%M%S") timestampDate = time.strftime("%d%m%Y") timestampSTART = timestampDate + '-' + timestampTime ChexnetTrainer.epochTrain (model, dataLoaderTrain, optimizer, scheduler, trMaxEpoch, nnClassCount, loss, epochID) val_loss = ChexnetTrainer.epochVal (model, dataLoaderVal, optimizer, scheduler, trMaxEpoch, nnClassCount, loss, epochID) timestampTime = time.strftime("%H%M%S") timestampDate = time.strftime("%d%m%Y") timestampEND = timestampDate + '-' + timestampTime scheduler.step(val_loss) if val_loss < lossMIN: lossMIN = val_loss torch.save({'epoch': epochID + 1, 'state_dict': model.state_dict(), 'best_loss': lossMIN, 'optimizer' : optimizer.state_dict()}, './models/m-' + launchTimestamp + '.pth.tar') print ('Epoch [' + str(epochID + 1) + '] [save] [' + timestampEND + '] loss= ' + str(val_loss)) else: print ('Epoch [' + str(epochID + 1) + '] [----] [' + timestampEND + '] loss= ' + str(val_loss))
train_dataloader = torch.utils.data.DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, num_workers=NUM_WORKERS) val_dataloader = torch.utils.data.DataLoader(val_dataset, batch_size=BATCH_SIZE, shuffle=False, num_workers=NUM_WORKERS) test_dataloader = torch.utils.data.DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False, num_workers=NUM_WORKERS) dataloaders = {'train': train_dataloader, 'val': val_dataloader} resnet = ResNet18().to(device) # Optimizer and loss function criterion = nn.CrossEntropyLoss() params_to_update = resnet.parameters() # Now we'll use Adam optimization optimizer = optim.Adam(params_to_update, lr=0.01) best_model, val_acc_history, loss_acc_history, time_elapsed = train_model( resnet, dataloaders, criterion, optimizer, 25, 'resnet18_bestsofar', device=device)